{"record":{"id":"6cd9827c198bbd17","repo":"stablyai/orca","slug":"windows-command-tokens-cannot-contain-quotes-or-li","errorCode":null,"errorMessage":"Windows command tokens cannot contain quotes or line breaks.","messagePattern":"Windows command tokens cannot contain quotes or line breaks\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/claude-accounts/windows-command-invocation.ts","lineNumber":9,"sourceCode":"export type WindowsCommandInvocation = {\n  command: string\n  args: string[]\n  windowsVerbatimArguments: true\n}\n\nfunction quoteCmdToken(value: string): string {\n  if (/[\\r\\n\"]/.test(value)) {\n    throw new Error('Windows command tokens cannot contain quotes or line breaks.')\n  }\n  const crtEscaped = value.replace(\n    /(\\\\*)$/,\n    (_match, backslashes: string) => `${backslashes}${backslashes}`\n  )\n  // Percent expansion still runs inside quotes, so briefly leave the quoted span to escape it.\n  return `\"${crtEscaped.replace(/%/g, '\"^%\"')}\"`\n}\n\nexport function buildWindowsCommandInvocation(\n  command: string,\n  args: string[],\n  commandInterpreter = process.env.ComSpec ?? 'cmd.exe'\n): WindowsCommandInvocation {\n  const commandLine = [command, ...args].map(quoteCmdToken).join(' ')\n  return {\n    command: commandInterpreter,\n    args: ['/d', '/v:off', '/s', '/c', `\"${commandLine}\"`],","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/claude-accounts/windows-command-invocation.ts#L1-L27","documentation":"Thrown by quoteCmdToken when a command or argument string contains a carriage return (\\r), newline (\\n), or double-quote (\"). This is a security guard preventing cmd.exe command injection through crafted tokens, since the quoting strategy (windowsVerbatimArguments with /s /c) cannot safely embed those characters.","triggerScenarios":"buildWindowsCommandInvocation is called with a command or arg containing quotes or line breaks. This happens when resolveClaudeCommand() returns a path with embedded quotes, or when an arg passed to Claude includes a newline (e.g., a multi-line prompt or config value).","commonSituations":"A file path with spaces was incorrectly pre-quoted by the caller (adding embedded quotes). A multi-line environment variable or argument is passed through. A user-supplied string with special characters reaches the command builder without sanitization.","solutions":["Do NOT pre-quote paths — buildWindowsCommandInvocation handles quoting internally. Pass raw unquoted paths.","Strip or reject newlines/quotes from user-supplied strings before passing them as command args.","If a multiline value is needed, write it to a temp file and pass the file path instead.","Audit the caller to ensure args are sanitized before reaching buildWindowsCommandInvocation."],"exampleFix":"// before: pre-quoted path with embedded quotes causes the guard to fire\nconst invocation = buildWindowsCommandInvocation('\"C:\\\\Program Files\\\\app\\\\orca.exe\"', args)\n// after: pass the raw path; quoteCmdToken adds the quotes\nconst invocation = buildWindowsCommandInvocation('C:\\\\Program Files\\\\app\\\\orca.exe', args)","handlingStrategy":"validation","validationCode":"function isSafeWindowsToken(value: string): boolean {\n  return !/[\\r\\n\"]/.test(value)\n}\n\n// Before building the invocation:\nif (!isSafeWindowsToken(command) || args.some(a => !isSafeWindowsToken(a))) {\n  throw new Error('Rejecting unsafe command token before Windows invocation')\n}","typeGuard":null,"tryCatchPattern":"try {\n  buildWindowsCommandInvocation(command, args)\n} catch (error) {\n  if (error instanceof Error && error.message.includes('cannot contain quotes or line breaks')) {\n    // Sanitize or reject the offending token\n    command = command.replace(/[\\r\\n\"]/g, '')\n  } else { throw error }\n}","preventionTips":["Never pre-quote paths before passing to buildWindowsCommandInvocation.","Sanitize user-supplied strings: strip quotes and newlines before use as command args.","Write multi-line values to temp files and pass file paths instead."],"tags":["windows","security","command-injection","cmd-exe","shell-quoting"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}