Files
claudetools/.claude/memory/feedback_windows_quote_stripping.md
Mike Swanson 2937b00ebf sync: auto-sync from GURU-5070 at 2026-07-01 15:49:56
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-07-01 15:49:56
2026-07-01 15:50:54 -07:00

3.1 KiB

name, description, metadata
name description metadata
feedback_windows_quote_stripping On Windows, embedded double-quotes in command args get stripped/mangled twice over — by PowerShell-invoked curl.exe (CommandLineToArgvW) and by the GuruRMM cmd shell layer. Build quoted args without literal embedded double-quotes.
type
feedback

MECHANICAL FIX FIRST (2026-07-01): for any PowerShell payload crossing a mangling layer (RMM dispatch, ScreenConnect command box, plink, curl.exe args), use .claude/scripts/ps-encoded.sh — it UTF-16LE-base64 encodes a script file and delivers it via powershell -EncodedCommand (encode prints the paste-safe one-liner; rmm <agent-uuid> <file> dispatches + polls via GuruRMM). Base64 has no quotes/backslashes/$ to strip, so the script arrives byte-exact (verified: UNC \\ survives). Author the script with the Write tool, not a bash heredoc (Git-bash heredocs collapse \\ even single-quoted). The manual rules below remain for one-off inline args only.

On Windows, embedded double-quotes inside a command argument get silently stripped or mangled at two separate layers we hit repeatedly. The body of the arg survives; the " characters vanish, so the receiving program sees broken syntax (an undefined constant, a usage dump, a parse error) — never a clean error that points at quoting.

Two confirmed failure layers:

  • curl.exe invoked from PowerShell — Windows re-parses the process command line via CommandLineToArgvW, which eats the inner " in --data-urlencode 'x="y"'. A pfSense diag_command.php PHP body became echo PHPRUNS-OK -> echo PHPRUNS -> "Undefined constant" (cost ~4 wasted RMM round-trips). (Howard, 2026-06-16.)
  • GuruRMM command_type:shell (cmd.exe) layershutdown /r /t 60 /c "comment" had its "comment" quotes mangled through the agent's cmd layer; shutdown rejected the args and dumped usage. Fix was to drop /c entirely. (2026-06-16.)

Why: It's the same root cause both times — Windows command-line re-tokenization (CommandLineToArgvW) strips a layer of double-quotes that a Unix shell would have preserved. PowerShell -> native exe, and RMM -> cmd.exe, each add a re-parse.

How to apply:

  • Don't put literal embedded double-quotes inside an arg you pass through PowerShell->curl.exe or RMM->cmd. Prefer single-quotes for the outer payload and construct any needed " from [char]34 (PowerShell) — keep the command on one line.
  • For JSON request bodies, use a single-quoted heredoc (<<'JSON') with --data-binary @- (per the Syncro/RMM skill rules) — that bypasses command-line re-parsing entirely. This is the reliable path.
  • If an arg with quotes is unavoidable, drop the quoted part (as with shutdown /c) or move the value into a file/variable the program reads itself.
  • Distinct-but-adjacent gotchas: non-ASCII chars in payload text also break on Windows/Git-bash (see feedback_ascii_only_api_payloads); /tmp resolves differently between Write and Git-bash (see feedback_tmp_path_windows); PowerShell variable names are case-insensitive (see the errorlog $gUid/$guid incident).