Opened 4 years ago
Last modified 5 weeks ago
#54484 assigned defect (bug)
REST API returns (empty) array for Meta but Schema has type object
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.1 | Priority: | normal |
| Severity: | normal | Version: | 4.7 |
| Component: | REST API | Keywords: | has-patch changes-requested |
| Focuses: | Cc: |
Description
When checking http://localhost/wp-json/wp/v2/posts (fresh setup) the meta field is an empty array:
[{"id":1,...,"meta":[],...}]
But the schema (localhost/wp-json/wp/v2/posts?_method=OPTIONS) has type definition object:
{
...,
"schema":{
"$schema":"http:\/\/json-schema.org\/draft-04\/schema#",
"title":"post",
"type":"object",
"properties":{
...,
"meta":{
"description":"Metafelder.",
"type":"object",
"context":[
"view",
"edit"
],
"properties":[
]
},
...
},
...
},
...
}
Either the schema is wrong and should be array or REST API should not return an empty array
I'm downloading the schema from my local WordPress instance in order to create POJOs and using those with Springs WebClient which results in the following error:
Error: JSON decoding error: Cannot deserialize value of type `com.acme.api.wp.Meta` from Array value (token `JsonToken.START_ARRAY`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.acme.api.wp.Meta` from Array value (token `JsonToken.START_ARRAY`) at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: com.acme.api.wp.Posts["meta"])
Manually changing type from object to array fixes it. But I'm not sure if the schema is wrong or the REST API is returning invalid data.
Change History (14)
#2
@
4 years ago
- Summary changed from REST API returns (empty) array for Post Meta but Schema has type object to REST API returns (empty) array for Meta but Schema has type object
#3
@
13 months ago
- Milestone changed from Awaiting Review to 6.9
- Owner set to flixos90
- Status changed from new to assigned
- Version changed from 5.8.2 to 4.7
I realize I am finding this ticket very late, but thank you for raising this @dtrunk90!
The type of meta is object, so that's all correct. But the problem is that an empty array in PHP becomes [] when JSON-encoded, it doesn't make a difference whether it's supposed to be a regular (indexed) array ([] in JS/JSON) or an associative array ({} in JS/JSON). So this is certainly a bug.
The workaround is to either use JSON_FORCE_OBJECT when JSON-encoding the data, or transform the empty array to an empty object (e.g. via new stdClass()).
I think the latter fix is what's needed here, since it has to be determined for each specific possibly empty array individually, based on the JSON schema of the data. I'm going to take a closer look at this.
This has been a bug ever since the REST API was introduced, therefore setting the version to 4.7.
This ticket was mentioned in PR #8712 on WordPress/wordpress-develop by @sukhendu2002.
12 months ago
#4
- Keywords has-patch added
This PR addresses an inconsistency in the WordPress REST API where an empty meta field was returned as [] (empty array), while the API schema specifies it should be {} (empty object). This primarily affects clients consuming the API in the default 'view' context.
The WP_REST_Posts_Controller::prepare_item_for_response() method now checks the request context. It only converts an empty meta array ([]) to an empty object ({}) if $request['context'] === 'view'. For the 'edit' context, it remains [].
The WP_REST_Blocks_Controller::filter_response_by_context() method has been updated to safely access the wp_pattern_sync_status key/property regardless of whether $data['meta'] is an array or an object.
Trac ticket:
This ticket was mentioned in Slack in #core by welcher. View the logs.
6 months ago
#6
@
6 months ago
- Keywords changes-requested added
This was reviewed in the 6.9 Bug Scrub today. The associated PR has some changes requested.
#7
@
6 months ago
- Milestone changed from 6.9 to 7.0
Since the RC1 release is coming soon, I'm punting this ticket to 7.0.
This ticket was mentioned in PR #10889 on WordPress/wordpress-develop by @vishalkakadiya.
2 months ago
#8
#9
@
2 months ago
@wildworks @welcher @flixos90 I have raised a fresh new PR for this, can someone from you review that? Thanks!
@vishalkakadiya commented on PR #10889:
2 months ago
#10
@westonruter Thank you for reviewing the PR. I have addressed the feedback now.
This ticket was mentioned in Slack in #core-test by nikunj8866. View the logs.
7 weeks ago
#12
@
7 weeks ago
Patch Testing Report
Patch Tested: https://github.com/WordPress/wordpress-develop/pull/10889
Environment
- WordPress: 7.0-beta1-61709-src
- PHP: 8.2.29
- Server: nginx/1.29.5
- Database: mysqli (Server: 8.4.8 / Client: mysqlnd 8.2.29)
- Browser: Firefox 148.0
- OS: Windows 10/11
- Theme: Twenty Twenty-Five 1.4
- MU Plugins:
- test-trac-54484.php
- Plugins:
- Test Reports 1.2.1
Steps taken
- Applied the PR diff on trunk using gh pr diff 10889 | git apply
- Created an MU plugin that registers a custom post type book with show_in_rest => true and custom-fields support, but no registered meta fields
- Created a sample book post (ID 7) via WP-CLI
- Tested http://localhost:8889/wp-json/wp/v2/books/7?_fields=meta with patch — returned {"meta":{}} (empty object)
- Reverted the patch using git checkout
- Tested the same URL without patch — returned {"meta":[]} (empty array, the bug)
- Re-applied the patch and ran PHPUnit tests: WP_Test_REST_Post_Meta_Fields (151 tests, 581 assertions),
WP_Test_REST_Posts_Controller (278 tests, 2627 assertions), REST_Blocks (17 tests, 26 assertions) — all passing
- ✅ Patch is solving the problem
Expected result
- Empty meta field should return {} (JSON object) instead of [] (JSON array), matching the REST API schema type definition of object
Additional Notes
- Default posts/pages have Gutenberg's footnotes meta registered, so their meta is never truly empty. A custom post type with no registered meta is needed to reproduce the bug.
- The patch also correctly handles the wp_pattern_sync_status meta in the blocks controller for both array and object
types.
Support Content
MU Plugin used for testing (mu-plugins/test-trac-54484.php):
<?php add_action( 'init', function () { register_post_type( 'book', array( 'label' => 'Books', 'public' => true, 'show_in_rest' => true, 'rest_base' => 'books', 'supports' => array( 'title', 'editor', 'custom-fields' ), ) ); });
Still the case for current dev version (5.9)
And it's the same for menu, menu-items and I guess many others which contains a meta "object".