<p dir="auto">If you validate a form field with, for instance, <code class="notranslate">Symfony\Component\Validator\Constraints\Length</code> and submit the form with the value of the field as an array, the <code class="notranslate">LengthValidator</code> will throw an <code class="notranslate">UnexpectedTypeException</code>, generating a 500 response, instead of adding a violation to the form field.</p>
<p dir="auto">I tried to work around this issue by adding a <code class="notranslate">Type</code> constraint, but the <code class="notranslate">Length</code> constraint seems to be validated first. I also believe that most of the constraints that are affected (see the bottom of this issue) should implicitly validate the type as well. Having to add <code class="notranslate">Constraints\Type("File")</code> to an already existing <code class="notranslate">Constraints\File</code> seems counter-intuitive to me.</p>
<p dir="auto">To reproduce this, consider the following form type:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;?php

namespace AppBundle\Form;

use Symfony\Component\Form\Extension\Core\Type as FormType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints;

class TestType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            -&gt;add('test', FormType\TextType::class, array(
                'constraints'   =&gt; array(
                    new Constraints\NotBlank(),
                    new Constraints\Length(5),
                ),
            ))
        ;
    }
}"><pre class="notranslate"><span class="pl-ent">&lt;?php</span>

<span class="pl-k">namespace</span> <span class="pl-v">AppBundle</span>\<span class="pl-v">Form</span>;

<span class="pl-k">use</span> <span class="pl-v">Symfony</span>\<span class="pl-v">Component</span>\<span class="pl-v">Form</span>\<span class="pl-v">Extension</span>\<span class="pl-v">Core</span>\<span class="pl-v">Type</span> <span class="pl-k">as</span> <span class="pl-v">FormType</span>;
<span class="pl-k">use</span> <span class="pl-v">Symfony</span>\<span class="pl-v">Component</span>\<span class="pl-v">Form</span>\<span class="pl-v">AbstractType</span>;
<span class="pl-k">use</span> <span class="pl-v">Symfony</span>\<span class="pl-v">Component</span>\<span class="pl-v">Form</span>\<span class="pl-v">FormBuilderInterface</span>;
<span class="pl-k">use</span> <span class="pl-v">Symfony</span>\<span class="pl-v">Component</span>\<span class="pl-v">OptionsResolver</span>\<span class="pl-v">OptionsResolver</span>;
<span class="pl-k">use</span> <span class="pl-v">Symfony</span>\<span class="pl-v">Component</span>\<span class="pl-v">Validator</span>\<span class="pl-v">Constraints</span>;

<span class="pl-k">class</span> <span class="pl-v">TestType</span> <span class="pl-k">extends</span> <span class="pl-v">AbstractType</span>
{
    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">buildForm</span>(<span class="pl-smi"><span class="pl-smi">FormBuilderInterface</span></span> <span class="pl-s1"><span class="pl-c1">$</span>builder</span>, <span class="pl-smi">array</span> <span class="pl-s1"><span class="pl-c1">$</span>options</span>)
    {
        <span class="pl-s1"><span class="pl-c1">$</span>builder</span>
            -&gt;<span class="pl-en">add</span>(<span class="pl-s">'test'</span>, <span class="pl-v">FormType</span>\<span class="pl-v">TextType</span>::class, <span class="pl-en">array</span>(
                <span class="pl-s">'constraints'</span>   =&gt; <span class="pl-en">array</span>(
                    <span class="pl-k">new</span> <span class="pl-v">Constraints</span>\<span class="pl-v">NotBlank</span>(),
                    <span class="pl-k">new</span> <span class="pl-v">Constraints</span>\<span class="pl-v">Length</span>(<span class="pl-c1">5</span>),
                ),
            ))
        ;
    }
}</pre></div>
<p dir="auto">If you submit the following request, you will receive an error page:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="POST / HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 19

test[test][foo]=bar"><pre class="notranslate"><code class="notranslate">POST / HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 19

test[test][foo]=bar
</code></pre></div>
<p dir="auto">This is due to the following piece of code which is present in <code class="notranslate">Symfony\Component\Validator\Constraints\LengthValidator</code>:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    public function validate($value, Constraint $constraint)
    {
        // [...]
        if (!is_scalar($value) &amp;&amp; !(is_object($value) &amp;&amp; method_exists($value, '__toString'))) {
            throw new UnexpectedTypeException($value, 'string');
        }
        // [...]
    }"><pre class="notranslate">    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">validate</span>(<span class="pl-s1"><span class="pl-c1">$</span>value</span>, <span class="pl-smi"><span class="pl-smi">Constraint</span></span> <span class="pl-s1"><span class="pl-c1">$</span>constraint</span>)
    {
        <span class="pl-c">// [...]</span>
        <span class="pl-k">if</span> (!is_scalar(<span class="pl-s1"><span class="pl-c1">$</span>value</span>) &amp;&amp; !(is_object(<span class="pl-s1"><span class="pl-c1">$</span>value</span>) &amp;&amp; method_exists(<span class="pl-s1"><span class="pl-c1">$</span>value</span>, <span class="pl-s">'__toString'</span>))) {
            <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-v">UnexpectedTypeException</span>(<span class="pl-s1"><span class="pl-c1">$</span>value</span>, <span class="pl-s">'string'</span>);
        }
        <span class="pl-c">// [...]</span>
    }</pre></div>
<p dir="auto">Similar checks seem to be present in the following constraints:<br>
<code class="notranslate">Country</code>, <code class="notranslate">Currency</code>, <code class="notranslate">DateTime</code>, <code class="notranslate">Date</code>, <code class="notranslate">Email</code>, <code class="notranslate">File</code>, <code class="notranslate">Iban</code>, <code class="notranslate">Ip</code>, <code class="notranslate">Isbn</code>, <code class="notranslate">Issn</code>, <code class="notranslate">Language</code>, <code class="notranslate">Length</code>, <code class="notranslate">Locale</code>, <code class="notranslate">Regex</code>, <code class="notranslate">Time</code>, <code class="notranslate">Url</code>, <code class="notranslate">Uuid</code></p>
<p dir="auto">I have this example, which i use in a small json-api where i use the form component to handle requests and validation.</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="-&gt;add('account', 'text', [
                'constraints' =&gt; [
                    new NotBlank(),
                    new Type('string'),
                    new Regex(&quot;/^XX\d+$/i&quot;)
                ]
            ])"><pre class="notranslate">-&gt;add(<span class="pl-s">'account'</span>, <span class="pl-s">'text'</span>, [
                <span class="pl-s">'constraints'</span> =&gt; [
                    <span class="pl-k">new</span> <span class="pl-v">NotBlank</span>(),
                    <span class="pl-k">new</span> <span class="pl-v">Type</span>(<span class="pl-s">'string'</span>),
                    <span class="pl-k">new</span> <span class="pl-v">Regex</span>("<span class="pl-s">/^XX\d+$/i</span>")
                ]
            ])</pre></div>
<p dir="auto">I have a form field for an accountname. The format of this name is <code class="notranslate">XX1234</code>.</p>
<p dir="auto">The validation above works great if the data being validated is a string. If i pass in an array instead of the string i will get an exception that is originating from here:</p>
<p dir="auto"><a href="https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Validator/Constraints/RegexValidator.php#L43">https://github.com/symfony/symfony/blob/2.8/src/Symfony/Component/Validator/Constraints/RegexValidator.php#L43</a></p>
<p dir="auto">In my opinion the validation should just fail here instead of throwing an exception. I pass an array in, and try to run an regexp on it. It seems obvious to me that something is wrong with the input data then and the validation should fail.</p>
<p dir="auto">Other validation constraints seems to work this way. Look at this example:</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="-&gt;add('disksize', 'text', [
                'constraints' =&gt; [
                    new NotBlank(),
                    new Type('numeric'),
                    new Range(['min' =&gt; 10, 'max' =&gt; 200])
                ]
            ])"><pre class="notranslate">-&gt;add(<span class="pl-s">'disksize'</span>, <span class="pl-s">'text'</span>, [
                <span class="pl-s">'constraints'</span> =&gt; [
                    <span class="pl-k">new</span> <span class="pl-v">NotBlank</span>(),
                    <span class="pl-k">new</span> <span class="pl-v">Type</span>(<span class="pl-s">'numeric'</span>),
                    <span class="pl-k">new</span> <span class="pl-v">Range</span>([<span class="pl-s">'min'</span> =&gt; <span class="pl-c1">10</span>, <span class="pl-s">'max'</span> =&gt; <span class="pl-c1">200</span>])
                ]
            ])</pre></div>
<p dir="auto">This works. I get an validation error and no exceptions. Other validations contraints, like <code class="notranslate">Length</code> seems to have the same problem as <code class="notranslate">Regex</code></p>
<p dir="auto">I think it would be great if all constraints just failed if they were passed an array if they cant handle an array. Or is there something i am overseeing?</p>
<p dir="auto">Is there some way i can work around this to make it fail validation if i pass in an array?</p>