Opened 2 months ago
Closed 5 weeks ago
#65035 closed defect (bug) (fixed)
Abilities: Strip internal schema keywords from abilities REST responses
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.0 | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Abilities API | Keywords: | has-patch has-unit-tests fixed-major dev-reviewed |
| Focuses: | Cc: |
Description
The Abilities REST API endpoint (/wp/v2/abilities) returns input_schema and output_schema that may contain WordPress-internal properties like sanitize_callback, validate_callback, and arg_options. These are not valid JSON Schema keywords and cause client-side JSON Schema validators to reject the schemas.
For example, a plugin registering an ability with register_ability() that includes sanitize_callback or arg_options in its schema arguments will surface those internal keywords in the REST response. Clients consuming the API (such as Gutenberg's AI tools integration) cannot validate these schemas without error.
Proposed Fix
Add a recursive strip_internal_schema_keywords() method to WP_REST_Abilities_V1_List_Controller that removes the three internal keywords from schemas before they appear in REST responses.
The method uses a denylist approach (array_diff_key() against a class constant INTERNAL_SCHEMA_KEYWORDS) rather than the allowlist approach (rest_get_allowed_schema_keywords() + array_intersect_key()) used in WP_REST_Server::get_data_for_route(). The denylist is the correct choice here because rest_get_allowed_schema_keywords() is missing valid JSON Schema keywords (allOf, not, definitions, dependencies, additionalItems) that would be silently stripped with the allowlist approach.
The recursive method traverses all JSON Schema sub-schema locations:
properties,patternProperties,definitions,dependencies(map-of-schemas)not,additionalProperties,additionalItems(single sub-schema)items(single schema or tuple array)anyOf,oneOf,allOf(array-of-schemas)
Property-dependency arrays (numeric arrays in dependencies) are correctly skipped.
The stripping is applied to both input_schema and output_schema in prepare_item_for_response().
Test Coverage
- Verifies internal keywords are stripped from top-level and nested properties in both
input_schemaandoutput_schema - Verifies internal keywords are stripped from all sub-schema locations (
anyOf,oneOf,allOf,not,patternProperties,definitions,dependencies,additionalProperties,additionalItems, tuple-styleitems) - Verifies valid JSON Schema keywords are preserved
- Verifies property-dependency arrays pass through unchanged
Related
- PR: wordpress-develop#11451
- Broader schema compilation tracking: #64955
Change History (8)
This ticket was mentioned in PR #11451 on WordPress/wordpress-develop by @jorgefilipecosta.
2 months ago
#2
Track ticket: https://core.trac.wordpress.org/ticket/65035
Ability input_schema and output_schema may contain WordPress-internal properties like sanitize_callback, validate_callback, and arg_options that are not valid JSON Schema keywords. These cause client-side JSON Schema validators to fail.
This adds recursive stripping of internal keywords in prepare_item_for_response(), using a denylist approach (array_diff_key removing specific internal keywords defined in WP_REST_Abilities_Controller::INTERNAL_SCHEMA_KEYWORDS). This differs from the allowlist approach (rest_get_allowed_schema_keywords() + array_intersect_key()) used in WP_REST_Server::get_data_for_route() — the denylist is the correct choice here because rest_get_allowed_schema_keywords() is missing valid JSON Schema keywords (allOf, not, definitions, dependencies, additionalItems) that would get silently stripped with the allowlist approach.
Related Gutenberg PR: https://github.com/WordPress/gutenberg/pull/77029
#4
@
2 months ago
- Owner set to jorgefilipecosta
- Resolution set to fixed
- Status changed from new to closed
In 62221:
#5
@
7 weeks ago
- Component changed from AI to Abilities API
Moving tickets related to the Abilities API to a new sub-component.
#6
@
5 weeks ago
- Keywords fixed-major dev-feedback added; dev-reviewed removed
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening for merge to the 7.0 branch pending committer sign off.
Reported by @ocean90 on the dev note: https://make.wordpress.org/core/2026/03/24/client-side-abilities-api-in-wordpress-7-0/#comment-48604
Tracked originally in Gutenberg: https://github.com/WordPress/ai/issues/346