abhigyanpatwari/GitNexus · error · Error
argument contains a double quote, unsafe for the Windows she
Error message
argument contains a double quote, unsafe for the Windows shell: ${JSON.stringify(arg)} What it means
Thrown by quoteWin32Arg() when a Windows command-line argument contains a double quote character. A literal " cannot be escaped reliably across the cmd.exe /c, npm.cmd %* re-parse, and node CRT argv layers, and it is additionally illegal in Windows paths and npm specs, so the helper rejects it instead of quoting. This is an injection/lint guard on arguments destined for a cmd.exe command line.
Source
Thrown at gitnexus/src/core/embeddings/runtime-install.ts:313
* Rules (validated against Node source, MS cmd/CRT docs, BatBadBut, Rust std):
* reject NUL/CR/LF and embedded `"` (both unrepresentable/unsafe at the cmd
* layer, and `"` is illegal in Windows paths and npm specs); wrap in double
* quotes when empty or containing whitespace/metacharacters; double the trailing
* backslash run so the added closing quote is not itself escaped (`C:\` →
* `"C:\\"`). `^` is literal inside cmd double quotes across all three parse
* layers (cmd `/c` → npm.cmd's `%*` re-parse → node CRT argv). Two documented
* ceilings quoting can't close: a defined `%VAR%` expands once at the first cmd
* parse, and `!` expands only under registry-enabled delayed expansion — both
* are the env-var owner's trust, out of the malicious-repo threat model.
*/
export const quoteWin32Arg = (arg: string): string => {
if (/[\0\r\n]/.test(arg)) {
throw new Error(
`argument contains NUL/CR/LF, unsafe for the Windows shell: ${JSON.stringify(arg)}`,
);
}
if (arg.includes('"')) {
throw new Error(
`argument contains a double quote, unsafe for the Windows shell: ${JSON.stringify(arg)}`,
);
}
if (arg !== '' && !WIN32_NEEDS_QUOTING.test(arg)) return arg;
const trailingBackslashes = /\\*$/.exec(arg)?.[0].length ?? 0;
return `"${arg}${'\\'.repeat(trailingBackslashes)}"`;
};
/**
* Compose a full `cmd.exe` command line: the command stays unquoted (so
* PATH/PATHEXT resolves a bare name or `.cmd` shim), args are individually
* quoted. Passing this as spawn's first (only) string argument — no args array
* — yields a byte-identical `cmd.exe /d /s /c "…"` line while avoiding DEP0190
* (the runtime deprecation warning Node >=24 emits for
* `spawn(file, args, {shell:true})`). Exported generically so the real-cmd.exe
* round-trip test drives the exact same composition the npm spawn uses.
*/
export const composeWin32Command = (command: string, args: string[]): string =>View on GitHub (pinned to aac7515d2a)
Solutions
- Remove or reject the double quote in the value before composing the command: if (arg.includes('"')) throw ... or strip/percent-encode as appropriate for the consumer.
- Fix the producer of the value — usually a JSON.stringify'd string or a copy-pasted shell fragment leaking a literal \" into the spec.
- Prefer spawn with an argument array and shell:false so no cmd.exe quoting round-trip is needed.
- For Windows paths, note \" is not a legal path character at all: treat its presence as corrupt input, not something to encode.
Example fix
// before
const spec = `onnxruntime-node@${userVersion}`; // userVersion = '\"1.19.0\"'
const cmdline = composeWin32Cmd('npm', ['install', spec]);
// -> Error: argument contains a double quote, unsafe for the Windows shell
// after
if (!/^[\w.\-+^~<>=| ,:]*$/.test(userVersion)) throw new Error('invalid version spec');
const cmdline = composeWin32Cmd('npm', ['install', `onnxruntime-node@${userVersion}`]); Defensive patterns
Strategy: validation
Validate before calling
// Allow-list the characters that can appear in npm specs/paths you pass on Windows.
export function assertSafeWin32Arg(arg: string): void {
if (arg.includes('"')) {
throw new Error(
`unsafe argument (double quote): ${JSON.stringify(arg)} — " is illegal in Windows paths and npm specs`,
);
}
}
assertSafeWin32Arg(`onnxruntime-node@${version}`); Type guard
export const isQuoteFreeArg = (arg: string): boolean => !arg.includes('"'); Try / catch
try {
cmdline = composeWin32Cmd(npmBin, args);
} catch (err) {
if (err instanceof Error && err.message.includes('double quote')) {
// A quoted string leaked into the spec (e.g. JSON.stringify output) — strip and retry.
const clean = args.map((a) => a.replaceAll('"', ''));
cmdline = composeWin32Cmd(npmBin, clean);
} else {
throw err;
}
} Prevention
- Never feed JSON.stringify output or copied shell snippets directly into spawn arguments.
- Validate version specs/package names against a character allow-list before building install commands.
- Use spawn with an args array and shell:false wherever the child supports it; reserve cmd.exe composition for .cmd shims only.
- Test the Windows code path in CI (wine or a windows runner) — these guards never fire on POSIX dev machines.
When it happens
Trigger: Calling quoteWin32Arg(arg) where arg includes \" — e.g. a package spec like pkg@\"1.0.0\", a path with a stray quote from templating/string concatenation, or untrusted input pasted into a config value that later becomes an install argument on Windows.
Common situations: Building npm install arguments from user-supplied version strings; shell snippets copied from documentation that include quotes; values produced by string interpolation of JSON-encoded strings. Only bites on Windows, where the cmd.exe code path is used.
Related errors
- argument contains NUL/CR/LF, unsafe for the Windows shell: $
- ${source} entry "${trimmed}" must be an identifier or member
- Path must not contain null bytes
- ${source}: branch name must not contain whitespace.
- ${source}: branch name must not start with "-".
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/20291ab69d0260e9.
Report an issue: GitHub.