[wp-trac] [WordPress Trac] #65035: Abilities: Strip internal schema keywords from abilities REST responses
WordPress Trac
noreply at wordpress.org
Tue Apr 7 13:22:52 UTC 2026
#65035: Abilities: Strip internal schema keywords from abilities REST responses
------------------------------+--------------------------------------
Reporter: jorgefilipecosta | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: 7.0
Component: AI | Version:
Severity: normal | Keywords: has-patch has-unit-tests
Focuses: |
------------------------------+--------------------------------------
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_schema}}} and {{{output_schema}}}
* Verifies internal keywords are stripped from all sub-schema locations
({{{anyOf}}}, {{{oneOf}}}, {{{allOf}}}, {{{not}}},
{{{patternProperties}}}, {{{definitions}}}, {{{dependencies}}},
{{{additionalProperties}}}, {{{additionalItems}}}, tuple-style
{{{items}}})
* Verifies valid JSON Schema keywords are preserved
* Verifies property-dependency arrays pass through unchanged
== Related ==
* PR: [https://github.com/WordPress/wordpress-develop/pull/11451
wordpress-develop#11451]
* Broader schema compilation tracking: #64955
--
Ticket URL: <https://core.trac.wordpress.org/ticket/65035>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list