garrytan/gstack · warning · Error
--out requires a file path
Error message
--out requires a file path
What it means
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.
Source
Thrown at browse/src/read-commands.ts:74
/**
* Parse `--out <path>` / `--out=<path>` and `--raw` / `--raw=true|false` out of an
* arg list, returning the flags plus the remaining positional args (`rest`).
*
* Single source of truth shared by the js/eval handlers and the write-capability
* gate in server.ts, so the two never disagree on what counts as an `--out`
* invocation. Throws on malformed usage (repeated `--out`, missing value, bad
* `--raw` value) so the user gets a clear error instead of a silent misparse.
*/
export function parseOutArgs(args: string[]): OutArgs {
let outPath: string | undefined;
let raw = false;
const rest: string[] = [];
for (let i = 0; i < args.length; i++) {
const a = args[i];
if (a === '--out') {
if (outPath !== undefined) throw new Error('--out specified more than once');
const val = args[i + 1];
if (val === undefined || val.startsWith('--')) throw new Error('--out requires a file path');
outPath = val;
i++;
} else if (a.startsWith('--out=')) {
if (outPath !== undefined) throw new Error('--out specified more than once');
const val = a.slice('--out='.length);
if (val === '') throw new Error('--out requires a file path');
outPath = val;
} else if (a === '--raw') {
raw = true;
} else if (a.startsWith('--raw=')) {
const v = a.slice('--raw='.length).toLowerCase();
if (v !== 'true' && v !== 'false') throw new Error('--raw must be true or false');
raw = v === 'true';
} else {
rest.push(a);
}
}
return { outPath, raw, rest };View on GitHub (pinned to 94993f7401)
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
Example fix
# before browse js 'document.title' --out # throws — no path browse js 'document.title' --out --raw # throws — next is a flag # after browse js 'document.title' --out ./out.json browse js 'document.title' --out=./out.json --raw
Defensive patterns
Strategy: validation
Validate before calling
function outHasValue(args: string[]): boolean {
for (let i = 0; i < args.length; i++) {
if (args[i] === '--out') {
const next = args[i + 1];
if (next === undefined || next.startsWith('--')) return false;
}
}
return true;
}
if (!outHasValue(args)) {
throw new Error('--out must be followed by a file path');
} Type guard
function outValueIsPresent(args: string[]): boolean {
for (let i = 0; i < args.length; i++) {
if (args[i] === '--out') {
const v = args[i + 1];
if (!v || v.startsWith('--')) return false;
}
}
return true;
} Try / catch
try {
parseOutArgs(args);
} catch (e: any) {
if (/--out requires a file path/.test(e.message)) {
// fall back to a default path
parseOutArgs([...args, './out.json']);
} else throw e;
} Prevention
- 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
When it happens
Trigger: `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.
Common situations: Forgetting the path entirely; misordered flags; shell word-splitting that turned an empty variable into nothing; copy-paste that dropped the path.
Related errors
- --out specified more than once
- --raw must be true or false
- --out: malformed base64 in data URL (decode would corrupt ou
- pdf: --from-file requires a path
- Unknown pdf flag: ${a}
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/61f0d31deec3f2d7.
Report an issue: GitHub.