Skip to content

Abilities API: Encode empty object results as JSON objects - #14547

Open
jorgefilipecosta wants to merge 1 commit into
WordPress:trunkfrom
jorgefilipecosta:fix/abilities-empty-object-result
Open

jorgefilipecosta wants to merge 1 commit into
WordPress:trunkfrom
jorgefilipecosta:fix/abilities-empty-object-result

Conversation

@jorgefilipecosta

@jorgefilipecosta jorgefilipecosta commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Follow up to https://core.trac.wordpress.org/changeset/64592 and #14139.

What

  • The run endpoint prepares every result for JSON clients with wp_prepare_json_value_for_client(), as the AI client already does, not only associative arrays. An empty array returned for an object output schema is now encoded as {} at the root, in lists, and inside object or JsonSerializable results, instead of [], which the JS client (executeAbility()) rejected with ability_invalid_output. This fixes it for all abilities, e.g. core/settings-get when no setting matches.
  • Arrays stay arrays: an empty list, a list of strings, or an empty array for a schema that also allows an array are still encoded as [].
  • The global _fields and _embed parameters, and response links, no longer fail with a fatal error on object data:
    • _rest_array_intersect_key_recursive() (_fields) and WP_REST_Server::embed_links() (_embed) leave non-array data unchanged. An empty object has no fields to filter and no links to embed.
    • WP_REST_Server::response_to_data() converts object data to an array before adding _links.
  • This also fixes the fatal from https://core.trac.wordpress.org/ticket/66230, e.g. /wp/v2/taxonomies?type=wingding&_fields=name now returns {}.
await wp.apiFetch( { path: wp.url.addQueryArgs( '/wp-abilities/v1/abilities/core/settings-get/run', { input: { group: 'writing', fields: [ 'title' ] } } ) } );
// Before: []
// After:  {}

await wp.apiFetch( { path: wp.url.addQueryArgs( '/wp-abilities/v1/abilities/core/settings-get/run', { input: { group: 'writing', fields: [ 'title' ] }, _fields: 'title' } ) } );
// After:  {}

Issue found while testing the query abilities through the JS client; the fix was drafted with AI assistance and reviewed by me.

Trac ticket: https://core.trac.wordpress.org/ticket/66267

Testing

Verify unit tests are passing:

npm run test:php -- --filter 'test_output_is_prepared_for_json_clients|test_no_matching_setting_is_encoded_as_an_empty_object|test_rest_filter_response_fields_empty_objects|test_link_embedding_empty_objects'

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props jorgefilipecosta, gziolo.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@jorgefilipecosta jorgefilipecosta changed the title Abilities API: Preserve empty object results in REST responses Abilities API: Return an empty object from core/settings-get when no setting matches Oct 20, 2026
@jorgefilipecosta
jorgefilipecosta force-pushed the fix/abilities-empty-object-result branch from 8e657ba to 29c2ab8 Compare October 20, 2026 13:05
@gziolo

gziolo commented Oct 20, 2026

Copy link
Copy Markdown
Member

I noted in #14139 that we should follow-up and figure out how to map [] to {} in a way that doesn't break REST API handler when global handlers like _fields or _links get passed. Casting to (object) in the ability doesn't resolve the problem.

@jorgefilipecosta
jorgefilipecosta force-pushed the fix/abilities-empty-object-result branch from 29c2ab8 to 0437a0b Compare October 20, 2026 13:26
@jorgefilipecosta jorgefilipecosta changed the title Abilities API: Return an empty object from core/settings-get when no setting matches Abilities API: Encode empty object results as JSON objects Oct 20, 2026
@jorgefilipecosta
jorgefilipecosta force-pushed the fix/abilities-empty-object-result branch from 0437a0b to e68fd10 Compare October 20, 2026 13:33
@jorgefilipecosta jorgefilipecosta changed the title Abilities API: Encode empty object results as JSON objects Abilities API: Return an empty object from core/settings-get when no setting matches Oct 20, 2026
@jorgefilipecosta
jorgefilipecosta force-pushed the fix/abilities-empty-object-result branch from e68fd10 to d05b08b Compare October 20, 2026 13:51
@jorgefilipecosta jorgefilipecosta changed the title Abilities API: Return an empty object from core/settings-get when no setting matches Abilities API: Encode empty object results as JSON objects Oct 20, 2026
The run endpoint prepared only associative array results for JSON
clients, so an empty array returned for an object output schema, such as
the `core/settings-get` result when no setting matches, was encoded as []
and failed output validation in JSON clients. Prepare every result,
including root results, lists and object results, so empty objects are
encoded as {} while arrays stay arrays.

The REST API's `_fields`, `_embed` and links processing expected array
data and failed with a fatal error on objects. Leave non-array data
unchanged when filtering fields or embedding links, since an empty
object has neither, and convert object data to an array when adding
links.

Follow-up to [64311], [64592].

See #66267, #66230.
@jorgefilipecosta
jorgefilipecosta force-pushed the fix/abilities-empty-object-result branch from d05b08b to 9d63d51 Compare October 20, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants