You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
wpgo raw mishandles quoted payloads and may hang on read-only meta checks #4
During CoMo Premium Exteriors May 2026 blog draft completion, wpgo raw was not reliable for workflows that needed quoted WordPress payloads. Commands involving values with spaces/quotes either mangled or stripped quoted values, making it unsafe for post titles, excerpts, Rank Math text fields, and schema payloads.
Impact
Could not safely use wpgo raw for Rank Math title/description/focus keyword writes.
Could not safely use wpgo raw for schema metadata payloads.
Required direct remote wp over WP Engine SSH as a workaround, usually by uploading/running a temporary wp eval-file helper.
This increases operator risk because workflows have to bypass the standard wrapper for text/meta/schema operations.
Observed workaround
Use direct SSH to WP Engine and run wp from the site docroot. For larger payloads, upload a temp PHP helper into _wpeprivate, run wp eval-file, then remove the helper.
In the same session, a simple read-only shell spot-check using wpgo raw ... post meta get ... did not return cleanly. This should be reproduced cleanly before treating it as a general read-path bug; it may be related to passthrough handling, quoting, or process/session behavior.
Suggested reproduction areas
wpgo raw post meta update <post_id> rank_math_title "Title With Spaces"
wpgo raw post meta update <post_id> rank_math_description "Description with spaces and punctuation"
wpgo raw post meta update <post_id> _rm_schema_blocks '<json-or-serialized-payload>'
wpgo raw post meta get <post_id> _thumbnail_id
Expected behavior
wpgo raw should preserve argv boundaries exactly as supplied by the caller and should return cleanly for read-only WP-CLI commands.
Actual behavior
Quoted values with spaces were not preserved reliably, and at least one read-only local invocation appeared to hang instead of returning a clean value.
Category: bug Summary:wpgo raw rebuilds the remote wp-cli command without preserving caller argv boundaries, so quoted payloads with spaces are split or stripped; at least one read-only meta get also failed to return cleanly. Current behavior:RawCmd passes every remaining argument as Command parts. Build concatenates those parts unescaped, while only Arg/Flag values go through shellEscape. A caller-supplied value such as Title With Spaces therefore becomes multiple remote tokens. Typed commands that use Arg already escape correctly. A read-only post meta get was observed not returning; that path uses context.Background() with no timeout on SSHClient.Exec. Desired behavior:wpgo raw must preserve argv boundaries exactly as supplied by the caller and must return cleanly for read-only WP-CLI commands. Key interfaces:RawCmd, Command.New, Command.Build, shellEscape, SSHClient.Exec Acceptance criteria:
wpgo raw post meta update <id> rank_math_title "Title With Spaces" delivers one remote argument containing the spaces
Description/punctuation and JSON-like schema payloads (including single quotes) are not stripped or mangled
wpgo raw post meta get <id> _thumbnail_id returns and exits without hanging
Existing Flag/Arg escape tests still pass; add coverage for raw passthrough with spaces and embedded quotes Out of scope: Changing typed wpgo command APIs; live Rank Math / WP Engine writes; keeping the temporary wp eval-file helper workflow
Sweep 2026-10-12 triage: PR #8 does not fix this issue. #8 forwards stdin for - arguments; this issue is about argv boundaries and a hang.
Argv boundaries: fix(backup): write database dumps outside the web root #7 (4ec1575) made the opposite design choice on purpose. raw joins its arguments with spaces and lets the server shell parse the line, and the README (### raw) tells callers to single-quote values with spaces, e.g. raw -- post meta update 7 title "'Spring cleaning tips'". The shell-syntax guards in checkRawArgs depend on that model. Escaping every argument, as the acceptance criteria here ask, would reverse fix(backup): write database dumps outside the web root #7's contract and require reworking those guards.
Hang on post meta get: RawCmd still calls ExecWP with context.Background() and no per-command deadline. That part is unaddressed.
Decision needed: keep #7's shell-line semantics and narrow this issue to a timeout for raw reads, or switch raw to argv-preserving escaping and rework the guards.
Closing (sweep 2026-10-12 decision). Argv handling: raw keeps the shell-line contract from #7 (4ec1575). Arguments are joined and parsed by the remote shell, the README's ### raw section tells callers to single-quote values with spaces, and checkRawArgs guards depend on that model, so switching to argv preservation would reverse a deliberate, documented design. Hang: the report came from a WP Engine site, and every WP Engine exec runs under wpengineSessionContext (internal/adapter/wpengine.go:63), a 10-minute deadline, so it cannot hang indefinitely. It was never reproduced. Piped-stdin handling was fixed separately in #8 (43b334f). Reopen with a reproducing command if a read hangs again.
Activity
itsjeremyjohnson commentedon Aug 17, 2026
Agent Brief
Category: bug
Summary:
wpgo rawrebuilds the remote wp-cli command without preserving caller argv boundaries, so quoted payloads with spaces are split or stripped; at least one read-only meta get also failed to return cleanly.Current behavior:
RawCmdpasses every remaining argument asCommandparts.Buildconcatenates those parts unescaped, while onlyArg/Flagvalues go throughshellEscape. A caller-supplied value such asTitle With Spacestherefore becomes multiple remote tokens. Typed commands that useArgalready escape correctly. A read-onlypost meta getwas observed not returning; that path usescontext.Background()with no timeout onSSHClient.Exec.Desired behavior:
wpgo rawmust preserve argv boundaries exactly as supplied by the caller and must return cleanly for read-only WP-CLI commands.Key interfaces:
RawCmd,Command.New,Command.Build,shellEscape,SSHClient.ExecAcceptance criteria:
wpgo raw post meta update <id> rank_math_title "Title With Spaces"delivers one remote argument containing the spaceswpgo raw post meta get <id> _thumbnail_idreturns and exits without hangingFlag/Argescape tests still pass; add coverage for raw passthrough with spaces and embedded quotesOut of scope: Changing typed wpgo command APIs; live Rank Math / WP Engine writes; keeping the temporary
wp eval-filehelper workflowitsjeremyjohnson commentedon Oct 12, 2026
Sweep 2026-10-12 triage: PR #8 does not fix this issue. #8 forwards stdin for
-arguments; this issue is about argv boundaries and a hang.4ec1575) made the opposite design choice on purpose.rawjoins its arguments with spaces and lets the server shell parse the line, and the README (### raw) tells callers to single-quote values with spaces, e.g.raw -- post meta update 7 title "'Spring cleaning tips'". The shell-syntax guards incheckRawArgsdepend on that model. Escaping every argument, as the acceptance criteria here ask, would reverse fix(backup): write database dumps outside the web root #7's contract and require reworking those guards.post meta get:RawCmdstill callsExecWPwithcontext.Background()and no per-command deadline. That part is unaddressed.Decision needed: keep #7's shell-line semantics and narrow this issue to a timeout for raw reads, or switch
rawto argv-preserving escaping and rework the guards.itsjeremyjohnson commentedon Oct 12, 2026
Closing (sweep 2026-10-12 decision). Argv handling:
rawkeeps the shell-line contract from #7 (4ec1575). Arguments are joined and parsed by the remote shell, the README's### rawsection tells callers to single-quote values with spaces, andcheckRawArgsguards depend on that model, so switching to argv preservation would reverse a deliberate, documented design. Hang: the report came from a WP Engine site, and every WP Engine exec runs underwpengineSessionContext(internal/adapter/wpengine.go:63), a 10-minute deadline, so it cannot hang indefinitely. It was never reproduced. Piped-stdin handling was fixed separately in #8 (43b334f). Reopen with a reproducing command if a read hangs again.