<p dir="auto"><strong>Symfony version(s) affected</strong>: 4.1.0</p>
<p dir="auto"><strong>Description</strong></p>
<p dir="auto">Symfony does not throw an exception <code class="notranslate">Circular reference detected for service "%s", path: "%s".</code> whenever I am using <code class="notranslate">!tagged</code> syntax.</p>
<p dir="auto"><strong>How to reproduce</strong></p>
<ol dir="auto">
<li>Create the following class:</li>
</ol>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;?php

namespace App\Services;

class MyService
{
    private $services;

    public function __construct(iterable $services)
    {
        $this-&gt;services = $services;
    }
}"><pre class="notranslate"><span class="pl-ent">&lt;?php</span>

<span class="pl-k">namespace</span> <span class="pl-v">App</span>\<span class="pl-v">Services</span>;

<span class="pl-k">class</span> <span class="pl-v">MyService</span>
{
    <span class="pl-k">private</span> <span class="pl-c1"><span class="pl-c1">$</span>services</span>;

    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">__construct</span>(<span class="pl-smi">iterable</span> <span class="pl-s1"><span class="pl-c1">$</span>services</span>)
    {
        <span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-&gt;<span class="pl-c1">services</span> = <span class="pl-s1"><span class="pl-c1">$</span>services</span>;
    }
}</pre></div>
<ol start="2" dir="auto">
<li>Create the following configuration:</li>
</ol>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    App\Services\MyService:
        arguments: ['@App\Services\MyService']"><pre class="notranslate">    <span class="pl-ent">App\Services\MyService</span>:
        <span class="pl-ent">arguments</span>: <span class="pl-s">['@App\Services\MyService']</span></pre></div>
<p dir="auto">Now we will get <code class="notranslate">Circular reference detected for service "App\Services\MyService", path: "App\Services\MyService -&gt; App\Services\MyService".</code>, it is fine.</p>
<ol start="3" dir="auto">
<li>Replace the configuration by the following code:</li>
</ol>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    App\Services\MyService:
        arguments:
          - !tagged my-service
        tags:
            - {name: 'my-service'}"><pre class="notranslate">    <span class="pl-ent">App\Services\MyService</span>:
        <span class="pl-ent">arguments</span>:
          - <span class="pl-k">!tagged</span> <span class="pl-s">my-service</span>
        <span class="pl-ent">tags</span>:
            - <span class="pl-s">{name: 'my-service'}</span></pre></div>
<p dir="auto">Symfony does not warn by exception about circular dependency. My real example was much more complex and actually it was my bug, but anyway would be nice to be informed about bug by semantic exception.</p>
<p dir="auto"><strong>Possible Solution</strong></p>
<p dir="auto">Throw <code class="notranslate">Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException</code> in such cases, or add simple console commend to check if we have circular dependency.</p>
<table role="table">
<thead>
<tr>
<th>Q</th>
<th>A</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bug report?</td>
<td>yes/no</td>
</tr>
<tr>
<td>Feature request?</td>
<td>no</td>
</tr>
<tr>
<td>BC Break report?</td>
<td>no</td>
</tr>
<tr>
<td>RFC?</td>
<td>no</td>
</tr>
<tr>
<td>Symfony version</td>
<td>3.4.3</td>
</tr>
</tbody>
</table>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class SomeInterface 
{
    public function supports(object $obj);
}

class ChainSome implements SomeInterface 
{
    /*
    * @var SomeInterface[]
    */
    private $somes;

    public function __construct(iterable $somes) 
    {
        $this-&gt;somes = $somes;
    }

    public function supports(object $obj)
    {
        foreach ($this-&gt;somes as $some) {
            if ($some-&gt;supports($obj)) {
                return true;
            }
        }        
    }
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">SomeInterface</span> 
{
    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">supports</span>(<span class="pl-smi"><span class="pl-smi">object</span></span> <span class="pl-s1"><span class="pl-c1">$</span>obj</span>);
}

<span class="pl-k">class</span> <span class="pl-v">ChainSome</span> <span class="pl-k">implements</span> <span class="pl-v">SomeInterface</span> 
{
    <span class="pl-c">/*</span>
<span class="pl-c">    * @var SomeInterface[]</span>
<span class="pl-c">    */</span>
    <span class="pl-k">private</span> <span class="pl-c1"><span class="pl-c1">$</span>somes</span>;

    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">__construct</span>(<span class="pl-smi">iterable</span> <span class="pl-s1"><span class="pl-c1">$</span>somes</span>) 
    {
        <span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-&gt;<span class="pl-c1">somes</span> = <span class="pl-s1"><span class="pl-c1">$</span>somes</span>;
    }

    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">supports</span>(<span class="pl-smi"><span class="pl-smi">object</span></span> <span class="pl-s1"><span class="pl-c1">$</span>obj</span>)
    {
        <span class="pl-k">foreach</span> (<span class="pl-s1"><span class="pl-c1">$</span><span class="pl-smi">this</span></span>-&gt;<span class="pl-c1">somes</span> <span class="pl-k">as</span> <span class="pl-s1"><span class="pl-c1">$</span>some</span>) {
            <span class="pl-k">if</span> (<span class="pl-s1"><span class="pl-c1">$</span>some</span>-&gt;<span class="pl-en">supports</span>(<span class="pl-s1"><span class="pl-c1">$</span>obj</span>)) {
                <span class="pl-k">return</span> <span class="pl-c1">true</span>;
            }
        }        
    }
}</pre></div>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="services:
    _instanceof:
        SomeInterface:
            tags:
                - { name: 'app.some' }

    ChainSome:
        arguments:
            $somes: !tagged app.some"><pre class="notranslate"><span class="pl-ent">services</span>:
    <span class="pl-ent">_instanceof</span>:
        <span class="pl-ent">SomeInterface</span>:
            <span class="pl-ent">tags</span>:
                - <span class="pl-s">{ name: 'app.some' }</span>

    <span class="pl-ent">ChainSome</span>:
        <span class="pl-ent">arguments</span>:
            <span class="pl-ent">$somes</span>: <span class="pl-s">!tagged app.some</span></pre></div>
<p dir="auto">In this example <code class="notranslate">ChainSome</code> receive instance of self and code reach infinity loop.<br>
Is this behavior is valid?<br>
Maybe possible exclude self injection?</p>