Opened 8 hours ago
Last modified 55 minutes ago
#66436 new enhancement
rest_validate_value_from_schema() should be able to report every validation error, not only the first
| Reported by: | zaguiini | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | REST API | Version: | |
| Severity: | normal | Keywords: | |
| Cc: | Focuses: |
Description
rest_validate_value_from_schema() stops at the first property that fails. In rest_validate_object_value_from_schema() the loop over properties returns the first WP_Error it meets (wp-includes/rest-api.php:2444-2449 in 7.1.4), and the same happens for pattern properties and for array items. A request with three bad fields produces one error, the client fixes it, sends again, and learns about the next one.
This was acceptable when a person read the error. It is costly for a program that talks to WordPress through the REST API or the Abilities API: each round trip is a full request, and an AI agent that calls an ability retries the same call once per bad field. The Abilities API validates ability input with this function (WP_Ability::validate_input(), wp-includes/abilities-api/class-wp-ability.php:536), so every ability on a site has this behavior and no plugin can change it without re-implementing the validator.
I propose that the validator can collect every error. A WP_Error already carries several codes and messages, so the result shape exists. Two options:
- A new argument or a filterable flag, off by default, that makes
rest_validate_value_from_schema()continue after a failure and return oneWP_Errorwith every failing property, each with its own message anddata.param. - A separate function, such as
rest_validate_value_from_schema_all(), that returns every error, withrest_validate_value_from_schema()unchanged.
Either way, the Abilities API could use it in validate_input() so an ability reports every invalid field in one response. I am happy to work on a patch once the direction is agreed.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
I confirmed that this still applies on trunk: object properties, pattern properties, additional properties, array items, and missing required properties stop at the first failure.
An explicit opt-in argument, disabled by default, seems worth exploring. That would preserve existing behavior while allowing callers such as the Abilities API to request all validation errors.
There are two details to account for before implementing this:
WP_Ability::validate_input()currently wraps only the first message from the validator. It would also need to preserve the collected errors.WP_Errordoes not preserve the proposed per-errordata.paramassociation through REST serialization. When several failures share a code such asrest_invalid_type,rest_convert_error_to_response()attaches the latest data for that code to every message. Each failure therefore needs a representation that keeps its code, message, and parameter path together.It would also help to clarify whether “every error” means all failing fields or every failed constraint within each field, and how errors from
anyOf/oneOfalternatives should be presented.One small update to the description: trunk now has the
wp_ability_validate_inputfilter, which allows plugins to augment or replace the result. It does not provide aggregate schema validation, so the underlying enhancement remains relevant.