Make WordPress Core

Opened 4 weeks ago

Last modified 4 weeks ago

#64921 accepted defect (bug)

REST API POST /wp/v2/posts: Undefined property stdClass::$id (line 766)

Reported by: swissspaceboy's profile swissspaceboy Owned by: westonruter's profile westonruter
Milestone: 7.1 Priority: normal
Severity: normal Version: 4.7
Component: General Keywords: has-patch needs-testing needs-test-info reporter-feedback
Focuses: rest-api Cc:

Description (last modified by sabernhardt)

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/posts with body: {"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 weeks ago
#1

  • Keywords has-patch added

Trac ticket: https://core.trac.wordpress.org/ticket/64921
## Use of AI Tools

#2 @sabernhardt
4 weeks ago

  • Description modified (diff)

#3 @abcd95
4 weeks 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 @swissspaceboy
4 weeks 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 @westonruter
4 weeks ago

  • Milestone changed from Awaiting Review to 7.1
  • Version changed from 6.9.4 to 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.

#6 @westonruter
4 weeks ago

  • Owner set to westonruter
  • Status changed from new to accepted

#7 @westonruter
4 weeks 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

Last edited 4 weeks ago by westonruter (previous) (diff)

This ticket was mentioned in PR #11336 on WordPress/wordpress-develop by @westonruter.


4 weeks 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 weeks ago

#10 @nikunj8866
4 weeks 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

  1. Enabled debug logging in wp-config.php:
    define('WP_DEBUG', true);
    define('WP_DEBUG_LOG', true);
    define('WP_DEBUG_DISPLAY', false);
    
  2. Installed and activated Easy Table of Contents 2.0.82.1.
  3. Enabled Table of Contents for Posts under Settings > Table of Contents.
  4. Created an Application Password via Users > Profile > Application Passwords.
  5. Sent the following POST request via Postman:
  6. 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.

#11 @nikunj8866
4 weeks ago

  • Keywords needs-test-info added

#12 @nikunj8866
4 weeks ago

  • Keywords reporter-feedback added
Note: See TracTickets for help on using tickets.