Problem/Motivation
At the moment we only have #limit_validation_errors for form elements of type button and submit. Using it it is possible to turn off validation completly or enable it only for desired regions. But there is no option to say what should not be validated.
Let's look at a simple example.
We have a form structure, which enables us to add more items to the form through ajax. Each of this items might have a required field. When the user submits the ajax call to add another item the form is automatically validated and if the user decided first to generate couple of items and then fill out the required fields in each of them, she will not be able to do this, as she is going to get error saying that some of the fields are required and a new item will not be generated.
Now the developer has the option to suppress the whole validation with setting
#limit_validation_errors = array()
But by using this even the custom validation introduced by the developer will be suppressed, e.g. the user should get a validation error, if she generated more than 10 items.
Instead there should be a possibility to generate items with required fields without filling them out and they should be validated only when the whole form is submitted and not on each ajax call.
For another description / use case see #33.
Proposed resolution
Introduce a new setting for the form control '#ajax' called 'suppress_required_fields_validation', which when set to TRUE, will force the FormValidator to skip validation of required fields for the ajax call this setting was set for.
A form element might then set the ajax form control with the setting suppress_required_fields_validation like this:
'#ajax' => array(
'callback' => 'my_custom_ajax_callback',
'wrapper' => 'my_custom_wrapper_id',
'effect' => 'fade',
'suppress_required_fields_validation' => TRUE,
),
Remaining tasks
User interface changes
none
API changes
New setting 'suppress_required_fields_validation' for the form controll '#ajax'.
The patch commited with the issue shows the changes needed to achieve this.
Issue fork drupal-2476569
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
Comment #1
hchonovComment #3
hchonovIntegrated a check, if required is set...
Comment #4
cspitzlayI can think of another use case that I find even more strange (and unfriendly to the user):
Suppose you had an "add item" and a "remove item" ajax button to add and remove elements with required fields on them.
Now the user can click "add another item" and easily get their new element. But to remove it he needs to enter all the required fields to make the validation pass so he is allowed to delete the element again.
Comment #5
hchonovHere a failing test demonstrating the use case.
Comment #7
hchonovand here the failing test with my fix.
Comment #10
hchonovAs #2263569: Bypass form caching by default for forms using #ajax. made several big changes, the previous patch will not apply anymore and needs to be adjusted.
So here a new version of the patch including the test.
I've also simplified the patch a lot.
Comment #12
hchonovNow checking in FormValidator::doValidateForm if there is an actual request existing before accessing its query.
Comment #13
tim.plunkettThe new test also passes if we just empty out #limit_validation_errors.
Why can't we just do it this way?
Maybe more test coverage will help illustrate.
Comment #14
hchonovYes, it works with the #limit_validation_errors as described in the IS, but as long as we have custom validation funcitons, which should run e.g. for a specific content type limit the field up to 2 items, then with #limit_validation_errors set the custom validate function will not set an error at adding the third item.
Here a new test demonstrating this use case, where the last assertion should fail.
Comment #16
hchonovExcuse me, I forgot to set the field as required in the last patch, but actually it makes no difference, with the #limit_validation_errors set to an empty array, no custom validation will be able to set errors.
Here again the test only with the field set as required.
Comment #17
hchonovAnd here again the patch including the extended test.
Comment #19
mgiffordPatch needs re-roll.
Comment #20
mohit_aghera commentedApplied patch in #17
Working fine. Updating patch.
Comment #21
mohit_aghera commentedComment #27
amateescu commentedThat's.. not true! I'm pretty sure you can use '#element_validate' together with '#limit_validation_errors = []' on a form element and the element validation handler will be called. I'd vote for a won't fix here :)
Comment #28
hchonovIt is not true, that it is not true, because if
'#limit_validation_errors'is an empty array then all messages are being filtered away.Take a look at the Form API documentation:
Further take a look at FormState::setErrorByName():
This means that if
'#limit_validation_errors'is an empty array, then the $record variable will stay FALSE and no errors will be recorded.I hope you could reconsider this now :).
Comment #31
iyyappan.govindHi
I am using Drupal Version 8.6.1. I have same problem in select drop-down ajax( a required field). I had this issue in Drupal 8.5.x. So I updated the Drupal to 8.6.1 but issue is not fixed. Please find the attachment
Comment #32
iyyappan.govindI have applied the patch also. But it is not working. Please help me to fix this issue. Thanks
Comment #33
geek-merlinThanks everyone for working on this! This bit us too and hard.
Our use case is the Ajax Dependency module. (Which in turn we need for our distribution's "conditional fields", as the jS-based conditional field module is too limited and imho currently broken beyond repair.)
On our organisation profile, we have an org_type field, which may be business, or nonprofit, or both, but must not be empty and thus is required. Using said module, we change access to other fields (like refs to nor-profit or non-profit taxonomy terms).
This issue bites us e.g. if a user 1) erroneously chooses 'nonprofit' 2) removes the 'nonprofit' checkmark, then the ajax call breaks as the reqired field now is empty thus invalid.
Note that setting nonrequired or limiting validation or hacking #element_validate is not an option, as the field must be required in the final submit. So we need a solution where there is no validation on ajax (exactly: the ajax triggered by a field change), but not on submit.
I even wonder if there is a use case for validating ajax-on-field-change that is a form rebuild and not a submit.
Comment #34
geek-merlinComment #35
geek-merlinComment #36
geek-merlinLet's see what el testbot says to this plain rebase.
Comment #38
geek-merlinNow with CS fixes.
Comment #40
geek-merlinOK. The rebased patch did not fix my use case. Also i realized that #limit_validation_errors on the ajax-on-value-change element fixes my use case.
To summarize:
* To suppress all validation when we want to only rebuild the form, use #limit_validation_errors=[]. It also works on ajax-on-value-change elements (which i did not realize first, also see the related docs issue)
* What the OP needed was to suppress only some validation on an element, but not their custom validation
So no contrib blocker at all, and "sorry for the noise" ;-).
Comment #45
jainv18 commented@geek-merlin - How did you resolve your issue with #limit_validation_errors ?
I am facing this issue a lot when having multiple select fields dependent on each other, once selecting a parent field the child field gets populated but when I change the parent field again, I get an error -
"An illegal choice has been detected. Please contact the site administrator."
I tried using limit_validation_errors on all the fields but no luck.
Can you please tell me where did you use it - in the form_alter or ajax_callback?
Comment #47
mlncn commentedI think i am in the same situation as JAINV18, currently blocking development of Focused Entity Reference.
Comment #48
avinashm commentedHi @JAINV18 and @mlncn
I was facing the same issue and used #limit_validation_errors property to fix it.
Here is the sample code.
NOTE: Reference taken from (#12) https://www.drupal.org/project/business_rules/issues/3051993
Comment #53
a.dmitriiev commentedI have now another use case:
The AI content suggestions would be nice to have as ajax callback, but the required field of the entity form could be skipped during validation, because for example you want the title to be suggested by AI and it is required.
I have re-rolled the patch for Drupal 11.1.x and removed the change in WidgetBase class, as it might be out of scope. Let's first create the possibility of skipping validation of required fields in general, so that contrib or custom modules can implement this in their code.
Comment #55
a.dmitriiev commentedI have also opened a MR for easier collaboration.
Comment #56
marcus_johansson commentedI'm currently using Claro and it looks like this:

Comment #57
a.dmitriiev commentedThe last comment is for issue #3489572: AI Content Suggestions: Allow summarize, analyze, suggest title and taxonomy terms based on the rendered HTML of the entity
Comment #59
a.dmitriiev commentedI have rebased the MR branch on current main.
Uploading the static patch for using in composer based projects
Comment #60
smustgrave commentedThis appears to be missing test coverage.
Comment #61
petar_basic commentedComment #62
petar_basic commentedAdded tests
Comment #63
fagoI must say, I was hesitant about the addition of #suppress_required_fields_validation when we already have #limit_validation_errors.
But the field_widget_actions use-case of AI actually demonstrates the need for #suppress_required_fields_validation. #limit_validation_errors cannot be used, since #limit_validation_errors completely skips validation + makes respective form-values not available (what's right, since they are not validated).
We want to keep the form validating, keep form values, but ONLY skip required-field validation. This is not possible atm and the new proposed
suppress_required_fields_validationfills the need.That said, I got convinced, it makes sense to add this.
However, I'm not sure about the proposed resolution design. Why is #suppress_required_fields_validation only working for ajax operations? Why are we not following #limit_validation_errors and make it possible for every submit-button? Whether or not the button uses AJAX or not seems to be a separate topic. Thus, shouldn't this be a general feature/option like #limit_validation_errors ?
Also, MR has a test fail, so this is needs work.
Comment #64
arianraeesi commentedComment #65
ahmad-khalil-imagexComment #66
ahmad-khalil-imagexRebased the MR branch on current main (
afe536a).The MR was 571 commits behind main, so I rebased locally to clear the merge conflict block. Two conflicts came up; both were structural, not behavioural:
core/lib/Drupal/Core/Form/FormBuilderInterface.php— main had added a newHTMX_REQUESTconstant in the same spot where this MR addsAJAX_SKIP_REQUIRED_VALIDATION. Resolved by keeping both constants with their respective docblocks.core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php— both sides added newusestatements in the imports block. Resolved by keeping all three (CsrfTokenGenerator,FormBuilderInterface,FormErrorHandlerInterface) in alphabetical order.No logic changes were needed in
FormValidator.php,RenderElementBase.php, or any of the test additions — those auto-merged cleanly.I also re-ran the manual test on the original (un-rebased) MR branch beforehand to confirm the feature works as intended:
'suppress_required_fields_validation' => TRUEon the AJAX trigger, clicking the button while a#requiredsibling field is empty fires the AJAX callback cleanly and produces no required-field error.FALSE(or absent), the same click produces the standard "field is required" error — confirming the flag is the deciding factor and that normal form submission still enforces required fields.Patch attached:
2476569-suppress-required-fields-validation-rebased.patch— 8 files changed, 193 insertions, 1 deletion. Cleanly applies on top ofafe536a7949.Comment #67
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. The merge request has merge conflicts and cannot be merged. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #68
a.dmitriiev commentedI have rebased the branch, the failing Workspace Media Library integration test looks irrelevant to this change.
Comment #69
smustgrave commentedWould be good to re-run that failed test to make sure please.
Comment #70
a.dmitriiev commentedIt is green now.
Comment #71
smustgrave commentedReading this again and is it really a bug or a feature request?
Regardless will need a change record though as a next step
Comment #72
abhisekmazumdarOn the scope of
suppress_required_fields_validation(re: @fago question from above)In my view I feel keeping this option scoped to
#ajaxis correct.AJAX callbacks are semantically intermediate operations, they rebuild the form, they do not submit it. Required fields exist to enforce data completeness at the point of final submission. Skipping required validation during a form rebuild is coherent, skipping it on a final submit is not.
A generalised, non-AJAX version of this option would allow a regular form submission to silently bypass required fields, a different use case, and a harmful one from a UX perspective.
If a developer needs to skip required validation on a non-AJAX button today,
#limit_validation_errors = []already exists for that, with the known tradeoff of suppressing custom#validatehandlers. That tradeoff is a separate problem worth solving separately.In my POV the
#ajaxboundary is the right semantic scope here.I have 1 security concern: the suppression flag is client-controllable
The current implementation reads the flag from the request query string in
FormValidator::doValidateForm(). It does not verify that the element which triggered the AJAX call actually declaredsuppress_required_fields_validation => TRUE. Any client can opt in by appending the parameter to any AJAX request.A concrete example:
Required-field validation is a UX constraint rather than a hard security gate, but bypassing it without form-author opt-in breaks the contract the form defines. Unless there is something in the core that will prevent it, which I'm not aware of.
I see this as a approach: check the triggering element's
#ajaxsettings server-side: for example, reading$form_state->getTriggeringElement()['#ajax']['suppress_required_fields_validation'], instead of trusting a client-supplied query parameter. The query param could then be dropped entirely maybe ?!Bug vs. feature (re: @smustgrave)
I too see this as a feature request (or task), not a bug.
AI disclosure: I used Claude Code to review the MR diff, analyse the tests, summarise the comment thread, and surface gaps. The reasoning and positions are my own. I reviewed everything before posting.
Comment #73
petar_basic commentedComment #74
petar_basic commentedPushed a rework implementing @abhisekmazumdar's suggestion: the opt-in is now read from the triggering element's server-side
#ajax['suppress_required_fields_validation']rather than a request parameter, so it can't be forced by a crafted request. I kept theajax_formcheck so it stays AJAX-only — if JS is off and the same button submits the full page, required validation still applies.Also removed the
AJAX_SKIP_REQUIRED_VALIDATIONconstant and its query-param injection in preRenderAjaxForm & added a test.On the scope question from #63: confirmed with @fago that we keep this scoped to
#ajax— it's for the intermediate AJAX rebuild, not the final submit.Created CR: https://www.drupal.org/node/3592386
Comment #75
abhisekmazumdarThe fixes done by @petar_basic look good to me.
Still needed before RTBC
1. Simplify the suppression check in
FormValidator.phpThere is an extra variable in the suppression logic that is not needed and makes the code harder to follow. The check already ensures suppression only applies to required fields by design, the extra gate is redundant. The flag should only check whether it is an AJAX request and whether the triggering element opted in.
2. Add a test proving custom validators still run
The core argument for this feature raised by @fago in #63: is that unlike
#limit_validation_errors = [], this option does not suppress custom element validators. That claim has no test backing it up. A unit test should confirm that whensuppress_required_fields_validationis TRUE, a custom#element_validatehandler still runs and its errors are still reported.3. Document the new
#ajaxoption in the Form APIsuppress_required_fields_validationis not mentioned in the#ajaxproperty documentation. A developer looking at the Form API docs has no way to discover this option exists. It needs a one-line entry wherever the other#ajaxsub-keys are documented.AI disclosure: I used Claude Code to review the MR diff, analyse the tests, summarise the comment thread, and surface gaps. The reasoning and positions are my own. I reviewed everything before posting.