Repository navigation
Studio Code: Read the file a wp_cli --post_content path names - #5305
Merged
Merged
Conversation
chubes4
marked this pull request as ready for review
October 23, 2026 00:08
Collaborator
📊 Performance Test ResultsComparing c62c4db vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
This was referenced Oct 23, 2026
chubes4
added a commit
that referenced
this pull request
Oct 23, 2026
…5310) ## Related issues - Follows #5305, which stopped `wp_cli post create|update --post_content=<file>` from saving the file's path. This PR handles another way a post gets saved wrong while the command still reports success. ## How AI was used Claude (via the Pi coding agent in a Roadie session) found the failure in eval transcripts, wrote the change and tests, and ran the eval below. I reviewed the diff and the results. ## Proposed Changes When `wp_cli post create|update --post_content=…` content starts with `{` but doesn't parse as JSON, the tool saves nothing and returns the parse error: ``` Nothing was saved: `--post_content` starts with `{` but is not valid JSON (Expected ',' or '}' after property value in JSON at position 174 (line 1 column 175)). WordPress ignores JSON post content that does not parse. ``` Block markup and HTML never start with `{`, so content that does is JSON, such as a Global Styles post. When WordPress can't parse a Global Styles post, it ignores the whole post. WP-CLI still saves it and prints `Success: Updated post 5.`, so the agent has no sign anything went wrong. That happened in an eval run of `global-styles-db-override`. The agent's JSON was missing its last `}`. Over the next 45 tool calls it checked the CSS, cleared transients, read the theme JSON resolver's source, and hex-dumped the post before finding the syntax error. The run used 1.4M tokens; the other runs used about 90k. The check is in `getUnsupportedWpCliPostContentMessage`, next to the existing `$(cat …)` refusal. It doesn't depend on post types or the database. It refuses instead of repairing because there's no single correct fix for broken JSON. ## Testing Instructions - `npx vitest run apps/cli/lib/tests/wp-cli-post-content.test.ts` covers the exact command from the failed run. It is refused with the parse error, and the same command with the brace restored is accepted. - **Replay on a real site:** the failed run's command, sent unchanged through `wp_cli`, was refused with the message above. The Global Styles post kept its previous valid content (`#f6efe4`, line height `1.7`). - **Eval:** `global-styles-db-override`, 6 runs on this branch. All 6 passed. | Run | Result | Tokens | Calls | What happened | |---|---|---|---|---| | 0 | Pass | 209k | 16 | Refused once, then saved valid JSON on the next call | | 1 | Pass | 110k | 10 | | | 2 | Pass | 209k | 14 | Refused once, then saved valid JSON on the next call | | 3 | Pass | 203k | 15 | | | 4 | Pass | 1029k | 42 | Saved with `wp` in Bash, which this check doesn't cover. Its JSON was missing the last `}`, and it took the same debugging spiral | | 5 | Pass | 200k | 13 | | In both refused runs, the agent's JSON was valid but `wp_cli` split the quoting wrong. Run 0 wrapped the whole argument in single quotes, so a trailing `'` ended up in the content. Run 2 escaped the inner double quotes with backslashes, so the content was cut to `{\`. On trunk, both would have been saved and reported as successful. - `npx vitest run apps/cli/ai apps/cli/lib/tests/wp-cli-post-content.test.ts` passes. Lint passes, and the typecheck shows only the existing errors in `commands/export.ts` and `commands/push.ts`. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors?
1 task done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related issues
post update 5 --post_content=<site>/tmp/header-new.html. That saved the path itself as the template part's content, which wiped the header the site renders, and the agent reported success.How AI was used in this PR
Claude (via the Pi coding agent in a Roadie session) wrote the change and the tests, and ran the checks below. I reviewed the diff and the tool output.
Proposed Changes
WP-CLI's
--post_contenttakes the content itself;post create <file>andpost update <id> <file>read it from a file. Whenpost createorpost updategets a--post_contentvalue that is the path of a file in the site folder (absolute or relative to it),wp_clinow runs the command with that file as the positional argument, so the post gets the file's content. The result says so:--porcelain) are split back out and kept.post createandpost updatechange. Every other command runs as written.post updatereads the first non-numeric argument as the file, so several IDs still work.--post_content=$(cat file)is still refused: shell syntax doesn't run, and that's a different mistake.Testing Instructions
npx vitest run apps/cli/lib/tests/wp-cli-post-content.test.ts apps/cli/aipasses (289). New tests cover an absolute path, a relative path with flags around it, five values that look like paths but aren't files, files outside the site folder, and other commands.tmp/x.htmlandtmp/y.html, then ran:post create --post_type=page --post_title=Probe --post_status=publish --post_content=<absolute path of x.html> --porcelain: page 6 created.post update 6 --post_content=tmp/y.html: page 6 updated.y.html's block markup. Without this change, the first command saves<path> --porcelainas the content.Pre-merge Checklist