To debug a form, use $form->getErrorsAsString() instead of $form->getErrors().
$form->getErrorsAsString() should only be used to debug the form...it will contain the errors of each child elements which is not the case of $form->getErrors().
As Peter mentions, $form->getErrors() will not return the sum of all the errors of the children forms.
To understand how a form can be invalid and have a getErrors() returning an empty array, you can have a look at the isValid() method of the symfony form class. As you can see, there are 2 cases where the form is not valid, the first one test for the general form, and the second case test for each child elements.
public function isValid()
{
//...
//CASE I : IF CHILD ELEMENTS HAVE ERRORS, $this->errors WILL CONTAIN
//THE ERROR ON THE CHILD ELEMENT AND NOT ON THE GENERAL 'errors' FIELD
//ITSELF
if (count($this->errors) > 0) {
return false;
}
//CASE II: AND THIS IS WHY WE ARE TESTING THE CHILD ELEMENTS AS WELL
//TO CHECK WHETHER THERE ARE VALID OR NOT
if (!$this->isDisabled()) {
foreach ($this->children as $child) {
if (!$child->isValid()) {
return false;
}
}
}
return true;
}
Therefore each form child can contain an error, but $form->getErrors() itself won't return all the errors. Considering a form that has many child elements, you will generally have $form->getErrors() with a CSRF error if the CSRF is not correct.