Problem/Motivation

On a node save, having a subfield:

  • Number field (decimal), unsigned, precision 10, scale 1.
  • Min value constraint
  • Submit with empty value

Other observations:

  • Setting the subfield required or not does not seem to matter
  • No issues with only max value constraint
  • Both or no constraints set also fine.
  • Main field required or not, cardinalitaty fixed or unlimited has no effect either.

Occurs both on 3.1.7 and 3.1.x.

Stack trace

Symfony\Component\Validator\Exception\ConstraintDefinitionException: The "Drupal\Core\Validation\Plugin\Validation\Constraint\RangeConstraint" constraint can not use "minMessage" and "maxMessage" when the "min" and "max" options are both set. Use "notInRangeMessage" instead. in Symfony\Component\Validator\Constraints\Range->__construct() (line 99 of /var/www/html/vendor/symfony/validator/Constraints/Range.php).

Drupal\Core\Validation\Plugin\Validation\Constraint\RangeConstraint->__construct() (Line: 31)
Drupal\Core\Validation\ConstraintFactory->createInstance() (Line: 83)
Drupal\Component\Plugin\PluginManagerBase->createInstance() (Line: 86)
Drupal\Core\Validation\ConstraintManager->create() (Line: 42)
Drupal\Core\Validation\Plugin\Validation\Constraint\ComplexDataConstraint->__construct() (Line: 31)
Drupal\Core\Validation\ConstraintFactory->createInstance() (Line: 83)
Drupal\Component\Plugin\PluginManagerBase->createInstance() (Line: 86)
Drupal\Core\Validation\ConstraintManager->create() (Line: 156)
Drupal\custom_field\Plugin\Field\FieldType\CustomItem->getConstraints() (Line: 45)
Drupal\Core\TypedData\Validation\TypedDataMetadata->getConstraints() (Line: 38)
Drupal\Core\TypedData\Validation\TypedDataMetadata->findConstraints() (Line: 152)
Drupal\Core\TypedData\Validation\RecursiveContextualValidator->validateNode() (Line: 164)
Drupal\Core\TypedData\Validation\RecursiveContextualValidator->validateNode() (Line: 164)
Drupal\Core\TypedData\Validation\RecursiveContextualValidator->validateNode() (Line: 106)
Drupal\Core\TypedData\Validation\RecursiveContextualValidator->validate() (Line: 93)
Drupal\Core\TypedData\Validation\RecursiveValidator->validate() (Line: 132)
Drupal\Core\TypedData\TypedData->validate() (Line: 518)
Drupal\Core\Entity\ContentEntityBase->validate() (Line: 188)
Drupal\Core\Entity\ContentEntityForm->validateForm()
call_user_func_array() (Line: 82)
Drupal\Core\Form\FormValidator->executeValidateHandlers() (Line: 274)
Drupal\Core\Form\FormValidator->doValidateForm() (Line: 118)
Drupal\Core\Form\FormValidator->validateForm() (Line: 593)
Drupal\Core\Form\FormBuilder->processForm() (Line: 326)
Drupal\Core\Form\FormBuilder->buildForm() (Line: 73)
Drupal\Core\Controller\FormController->getContentResult() (Line: 39)
Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController->getContentResult()
call_user_func_array() (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 638)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 121)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 181)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 53)
Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle() (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle() (Line: 116)
Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 90)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle() (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 741)
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

andreasderijcke created an issue. See original summary.

andreasderijcke’s picture

Issue summary: View changes
andreasderijcke’s picture

Issue summary: View changes
andreasderijcke’s picture

andreasderijcke’s picture

Should have been fixed in #3518147: Cannot set both min and max values for numeric fields.
Perhaps it customisations that are interferring. Will double check later this week.

apmsooner’s picture

Status: Active » Postponed (maintainer needs more info)

This should already be fixed in previous release but dev branch also has some additional logic that should make it more sound as well. Can confirm if this is still an issue in dev at least.

apmsooner’s picture

Assigned: andreasderijcke » Unassigned
Status: Postponed (maintainer needs more info) » Closed (cannot reproduce)

I'm not able to reproduce this on latest release. Feel free to reopen with steps to reproduce if you're still seeing this issue.

marksmith’s picture

Yeah, indeed. I was able to reproduce this on a fresh ddev install with only custom_field (and admin_toolbar) contrib module enabled. Tried with multiple versions of Drupal (10.5.1, 11.1.8, 11.2.2).

The solution I posted in my earlier reporting of this problem here still appears to solve the error on my test site.

andreasderijcke’s picture

Assigned: Unassigned » andreasderijcke
Status: Closed (cannot reproduce) » Active

Found the culprit.

The code from marksmith (https://www.drupal.org/project/custom_field/issues/3518147#comment-16060456) does not have the problem, but in the final refactored version, adding the constraint values is done if they have a value, not if the constraint is actually set. That causes the problem if you have a min or max constraint message set here: https://github.com/symfony/symfony/blob/7.3/src/Symfony/Component/Valida...

MR coming up.

andreasderijcke’s picture

Assigned: andreasderijcke » Unassigned
Status: Active » Needs review

Third try is hopefully sound.

So, the problem occurred for non-float numerical fields that only have a min or max set on the field, but still have the DB restrictions applied.
In that case, changing the minMessage/maxMessage to notInRangeMessage should fix it.

andreasderijcke’s picture

Title: The "Drupal\Core\Validation\Plugin\Validation\Constraint\RangeConstraint" constraint can not use "minMessage" and "maxMessage" when the "min" and "max" options are both set. Use "notInRangeMessage" instead. » Numerical field constraint fail when only min or max constraint is set

apmsooner’s picture

Status: Needs review » Fixed

apmsooner’s picture

Status: Fixed » Closed (fixed)