{"record":{"id":"61f0d31deec3f2d7","repo":"garrytan/gstack","slug":"out-requires-a-file-path","errorCode":null,"errorMessage":"--out requires a file path","messagePattern":"--out requires a file path","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"browse/src/read-commands.ts","lineNumber":74,"sourceCode":"/**\n * Parse `--out <path>` / `--out=<path>` and `--raw` / `--raw=true|false` out of an\n * arg list, returning the flags plus the remaining positional args (`rest`).\n *\n * Single source of truth shared by the js/eval handlers and the write-capability\n * gate in server.ts, so the two never disagree on what counts as an `--out`\n * invocation. Throws on malformed usage (repeated `--out`, missing value, bad\n * `--raw` value) so the user gets a clear error instead of a silent misparse.\n */\nexport function parseOutArgs(args: string[]): OutArgs {\n  let outPath: string | undefined;\n  let raw = false;\n  const rest: string[] = [];\n  for (let i = 0; i < args.length; i++) {\n    const a = args[i];\n    if (a === '--out') {\n      if (outPath !== undefined) throw new Error('--out specified more than once');\n      const val = args[i + 1];\n      if (val === undefined || val.startsWith('--')) throw new Error('--out requires a file path');\n      outPath = val;\n      i++;\n    } else if (a.startsWith('--out=')) {\n      if (outPath !== undefined) throw new Error('--out specified more than once');\n      const val = a.slice('--out='.length);\n      if (val === '') throw new Error('--out requires a file path');\n      outPath = val;\n    } else if (a === '--raw') {\n      raw = true;\n    } else if (a.startsWith('--raw=')) {\n      const v = a.slice('--raw='.length).toLowerCase();\n      if (v !== 'true' && v !== 'false') throw new Error('--raw must be true or false');\n      raw = v === 'true';\n    } else {\n      rest.push(a);\n    }\n  }\n  return { outPath, raw, rest };","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/read-commands.ts#L56-L92","documentation":"Thrown by parseOutArgs when `--out` (space form) is followed by nothing (end of args) or by another flag (a token starting with --). The parser treats the next token as the path only if it exists and does not look like a flag.","triggerScenarios":"`browse js <expr> --out` at the end of the arg list, or `browse js <expr> --out --raw` where the token after --out is itself a flag.","commonSituations":"Forgetting the path entirely; misordered flags; shell word-splitting that turned an empty variable into nothing; copy-paste that dropped the path.","solutions":["Provide a path immediately after --out","Use the --out=path form to avoid ambiguity with following flags","Guard empty shell variables: `${OUT:?missing}` or quote explicitly","Check arg ordering — put --out last or use the equals form"],"exampleFix":"# before\nbrowse js 'document.title' --out            # throws — no path\nbrowse js 'document.title' --out --raw      # throws — next is a flag\n\n# after\nbrowse js 'document.title' --out ./out.json\nbrowse js 'document.title' --out=./out.json --raw","handlingStrategy":"validation","validationCode":"function outHasValue(args: string[]): boolean {\n  for (let i = 0; i < args.length; i++) {\n    if (args[i] === '--out') {\n      const next = args[i + 1];\n      if (next === undefined || next.startsWith('--')) return false;\n    }\n  }\n  return true;\n}\n\nif (!outHasValue(args)) {\n  throw new Error('--out must be followed by a file path');\n}","typeGuard":"function outValueIsPresent(args: string[]): boolean {\n  for (let i = 0; i < args.length; i++) {\n    if (args[i] === '--out') {\n      const v = args[i + 1];\n      if (!v || v.startsWith('--')) return false;\n    }\n  }\n  return true;\n}","tryCatchPattern":"try {\n  parseOutArgs(args);\n} catch (e: any) {\n  if (/--out requires a file path/.test(e.message)) {\n    // fall back to a default path\n    parseOutArgs([...args, './out.json']);\n  } else throw e;\n}","preventionTips":["Always provide a path immediately after --out","Prefer the --out=path form to avoid ambiguity with following flags","Guard empty shell variables: `${OUT:?missing}`","Put --out last in the arg list to avoid flag-ordering traps"],"tags":["cli","args","missing-value","out-flag"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}