Opened 4 months ago
Last modified 4 months ago
#64921 accepted defect (bug)
REST API POST /wp/v2/posts: Undefined property stdClass::$id (line 766)
| Reported by: | swissspaceboy | Owned by: | westonruter |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.1 |
| Component: | General | Version: | 4.7 |
| Severity: | normal | Keywords: | has-patch needs-testing needs-test-info reporter-feedback |
| Cc: | Focuses: | rest-api |
Description (last modified by )
Creating posts via the standard WordPress REST API (POST /wp/v2/posts) generates PHP warnings in class-wp-rest-posts-controller.php.
Warnings
PHP Warning: Undefined property: stdClass::$id in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php on line 766 PHP Warning: Undefined property: stdClass::$post_parent in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php on line 769
Steps to reproduce
- Authenticate via Application Password (Basic Auth)
- Send
POST /wp-json/wp/v2/postswithbody: {"title": "Test", "content": "<p>Hello</p>", "status": "draft"} - Post is created successfully, but warnings are logged
Environment
WordPress 6.9.4
PHP 8.3
Apache / LiteSpeed
Confirmed on 3 independent installations
Site A: WordPress + Polylang
Site B: WordPress + Polylang
Site C: WordPress only (no Polylang, no multilingual plugin)
All 3 produce identical warnings, confirming this is a core issue.
Impact
- Post creation works — no functional breakage
- 2 PHP warnings per REST API call pollute php-error.log
- Automated workflows creating multiple posts amplify the log noise
Analysis
Lines 766-769 of class-wp-rest-posts-controller.php access $post->id and $post->post_parent on a stdClass object that lacks these properties. The $post object returned at this stage appears incomplete — possibly a regression in how prepare_item_for_response() receives the newly created post.
Expected behavior
No PHP warnings when creating posts via REST API.
Change History (12)
This ticket was mentioned in PR #11327 on WordPress/wordpress-develop by @immeet94.
4 months ago
#1
- Keywords has-patch added
#3
@
4 months ago
- Keywords needs-testing added
Reproduction Report
Description
This report validates whether the reported issue can be reproduced.
Environment
WordPress: 6.9.4-src
PHP: 8.3.30
Server: nginx/1.29.5
Database: mysqli (Server: 8.4.8 / Client: mysqlnd 8.3.30)
Browser: Chrome 146.0.0.0
OS: macOS
Theme: Twenty Twenty-Five 1.4
MU Plugins: None activated
Plugins:
Test Reports 1.2.0
Actual Results
❌ Error condition does not occur (not reproduced).
Successfully created a post via POST /wp-json/wp/v2/posts.
No PHP warnings were observed in logs during or after the request.
Additional Notes
The environment was explicitly switched to the 6.9.4 tag from wordpress-develop and rebuilt before testing.
Debug logging was enabled, but no warnings related to stdClass::$id or stdClass::$post_parent were generated.
This suggests the issue may be environment-specific, dependent on additional factors (e.g., plugins, configuration), or not reproducible in a clean setup.
#4
@
4 months ago
Hi,
Thanks for the reproduction test. Per further analysis, it is probably related to a shared plugin called "Easy Table of Contents".
I will write to the plugin author to get this fixed.
Many thanks for your help. Ticket can be closed.
Didier.
#5
@
4 months ago
- Milestone Awaiting Review → 7.1
- Version 6.9.4 → 4.7
It's still an issue, though, as core should be more resilient to how plugins are filtering the post object being inserted. I'm assuming this is due to the plugin filtering "rest_pre_insert_{$this->post_type}". It's clear that this is also closely related to code quality which would have been identified by implementing PHPStan static analysis (see #64898), as I can see many issues where assumptions are made about what types will be in WP_REST_Posts_Controller. So I'll make some type improvements and look at bypassing the unique slug check when there is no ID.
#7
@
4 months ago
Oh, what's more, is that the existing logic is wrong even in the ideal case because $prepared_post->id shouldn't ever exist. The valid property is $prepared_post->ID because \WP_REST_Posts_Controller::prepare_item_for_database() returns a faux-WP_Post object, not a post object prepared for the REST API response.
I see this was also caught by @immeet94 in https://github.com/WordPress/wordpress-develop/pull/11327
This ticket was mentioned in PR #11336 on WordPress/wordpress-develop by @westonruter.
4 months ago
#8
This primarily is for fixing calls to wp_unique_post_slug() in \WP_REST_Posts_Controller::create_item() and \WP_REST_Posts_Controller::update_item(). However, as part of that I also looked at WP_REST_Posts_Controller::prepare_item_for_database() and all methods that called it to ensure that they also had their static analysis issues addressed. I don't intend to commit this entire PR as-is. Subsets would be committed at a time, ideally with tests to catch the holes identified by static analysis
Trac ticket: https://core.trac.wordpress.org/ticket/64921
## Use of AI Tools
This ticket was mentioned in Slack in #core-test by ozgur_sar. View the logs.
4 months ago
#10
@
4 months ago
Reproduction Report
Description
❌ This report validates that the reported issue can not be reproduced.
Environment
- WordPress: 6.9.4
- PHP: 8.3.29
- Server: Apache/2.4.43 (Win32) mod_fcgid/2.3.9a
- Database: mysqli (Server: 10.6.23-MariaDB / Client: mysqlnd 8.3.29)
- Browser: Chrome 146.0.0.0
- OS: Windows 10/11
- Theme: Twenty Twenty-Five 1.4
- MU Plugins: None activated
- Plugins:
- Easy Table of Contents 2.0.82.1
- Test Reports 1.2.1
Steps to Reproduce
- Enabled debug logging in wp-config.php:
define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); - Installed and activated Easy Table of Contents 2.0.82.1.
- Enabled Table of Contents for Posts under Settings > Table of Contents.
- Created an Application Password via Users > Profile > Application Passwords.
- Sent the following POST request via Postman:
- URL: http://yoursite.com/wp-json/wp/v2/posts
- Method: POST
- Authorization: Basic Auth (username + application password)
- Body (raw JSON):
{ "title": "Test Post", "content": "<p>Hello</p>", "status": "draft" }
- Checked wp-content/debug.log for PHP warnings after the request.
Actual Results
❌ Error condition does not occur (not reproduced).
- Post was created successfully (HTTP 201 response received in Postman).
- No PHP warnings related to stdClass::$id or stdClass::$post_parent were found in wp-content/debug.log.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Trac ticket: https://core.trac.wordpress.org/ticket/64921
## Use of AI Tools