garrytan/gstack · warning · Error

--raw must be true or false

Error message

--raw must be true or false

What it means

Thrown by parseOutArgs when `--raw=<value>` is supplied with a value other than true or false (case-insensitive). The parser only accepts the two boolean literals; any other string is refused to avoid a silent default.

Source

Thrown at browse/src/read-commands.ts:86

  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 };
}

/**
 * True iff an arg list contains an `--out` flag in any accepted form
 * (`--out <path>` or `--out=<path>`). Used by the write-capability gate to
 * decide whether an otherwise-read command (`js`/`eval`) is actually a write
 * invocation. Mirrors parseOutArgs's `--out` recognition exactly. Never throws —
 * a malformed `--out=` still counts as an out attempt (fail safe: gate it).
 */
export function hasOutArg(args: string[]): boolean {
  return args.some(a => a === '--out' || a.startsWith('--out='));
}

View on GitHub (pinned to 94993f7401)

Solutions

  1. Use --raw=true or --raw=false (case-insensitive)
  2. Use the bare --raw flag as a shorthand for true
  3. Omit --raw entirely if you want the default (false)
  4. Check for typos in the literal — 'flase', 'ture', 'flase' are common

Example fix

# before
browse js 'render()' --out=img.png --raw=yes   # throws

# after
browse js 'render()' --out=img.png --raw=true
# or shorthand
browse js 'render()' --out=img.png --raw
Defensive patterns

Strategy: validation

Validate before calling

function rawValueIsValid(args: string[]): boolean {
  return args.every(a => {
    if (!a.startsWith('--raw=')) return true;
    const v = a.slice('--raw='.length).toLowerCase();
    return v === 'true' || v === 'false';
  });
}

if (!rawValueIsValid(args)) {
  throw new Error('--raw must be true or false (case-insensitive)');
}

Type guard

function isBooleanLiteral(s: string): boolean {
  const v = s.toLowerCase();
  return v === 'true' || v === 'false';
}

Try / catch

try {
  parseOutArgs(args);
} catch (e: any) {
  if (/--raw must be true or false/.test(e.message)) {
    // normalize: replace bad --raw=X with bare --raw
    const cleaned = args.filter(a => !a.startsWith('--raw=')).concat(['--raw']);
    parseOutArgs(cleaned);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing `--raw=yes`, `--raw=1`, `--raw=on`, `--raw=enable`, or a typo like `--raw=flase`.

Common situations: Boolean convention mismatch from other tools (1/0, yes/no, on/off); copy-paste from a config that uses a different boolean dialect; typo in the literal.

Related errors


AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12). Data as JSON: /api/errors/47c9ed541b07d0f3. Report an issue: GitHub.