garrytan/gstack · warning · Error
--out specified more than once
Error message
--out specified more than once
What it means
Thrown by parseOutArgs when `--out <path>` (space-separated form) appears a second time in the same js/eval command. The parser tracks the first outPath and refuses a second to avoid a silent overwrite of the output target.
Source
Thrown at browse/src/read-commands.ts:72
}
/**
* 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);
}View on GitHub (pinned to 94993f7401)
Solutions
- Remove the duplicate --out — only one output path is allowed per command
- Audit wrapper scripts and aliases that append --out automatically
- Use --out=path form exactly once, explicitly
- Build arg arrays with a Set or guard rather than naive push
Example fix
// before browse js 'document.title' --out a.json --out b.json // throws // after browse js 'document.title' --out a.json
Defensive patterns
Strategy: validation
Validate before calling
function hasSingleOutArg(args: string[]): boolean {
return args.filter(a => a === '--out' || a.startsWith('--out=')).length <= 1;
}
if (!hasSingleOutArg(args)) {
throw new Error('Only one --out flag is allowed per command');
} Type guard
function outArgCount(args: string[]): number {
return args.filter(a => a === '--out' || a.startsWith('--out=')).length;
} Try / catch
try {
parseOutArgs(args);
} catch (e: any) {
if (/--out specified more than once/.test(e.message)) {
// keep only the first --out occurrence
const deduped: string[] = [];
let seen = false;
for (let i = 0; i < args.length; i++) {
if (args[i] === '--out' || args[i].startsWith('--out=')) {
if (seen) continue;
seen = true;
if (args[i] === '--out') { deduped.push(args[i], args[i + 1]); i++; }
else deduped.push(args[i]);
} else deduped.push(args[i]);
}
parseOutArgs(deduped);
} else throw e;
} Prevention
- Dedupe the arg array before passing it to the command
- Audit wrapper scripts and aliases that inject --out automatically
- Use --out= exactly once, explicitly
- Build arg arrays with a guard: only push --out if outPath is not already set
When it happens
Trigger: Passing `browse js <expr> --out a.png --out b.png` — the second --out triggers the check because outPath is already set.
Common situations: Script or wrapper that appends --out automatically on top of a user-supplied --out; copy-paste duplication; shell alias that injects --out; arg array built by concatenation that double-adds the flag.
Related errors
- --out requires a file path
- --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/a5685ccab712c3f0.
Report an issue: GitHub.