chenglou/pretext · error · Error

Unsupported browser ${browser}; expected chrome or safari

Error message

Unsupported browser ${browser}; expected chrome or safari

What it means

Thrown by parseBrowser in corpus-check.ts. The browser selector resolves from `--browser=<value>`, else `CORPUS_CHECK_BROWSER`, else the literal default 'chrome', then lowercases. corpus-check supports only chrome and safari (Firefox corpus support is intentionally absent), so any other value throws, listing the two allowed options.

Source

Thrown at scripts/corpus-check.ts:137

  const prefix = `--${name}=`
  const arg = process.argv.find(value => value.startsWith(prefix))
  return arg === undefined ? null : arg.slice(prefix.length)
}

function parseNumberFlag(name: string, fallback: number): number {
  const raw = parseStringFlag(name)
  if (raw === null) return fallback
  const parsed = Number.parseInt(raw, 10)
  if (!Number.isFinite(parsed)) {
    throw new Error(`Invalid value for --${name}: ${raw}`)
  }
  return parsed
}

function parseBrowser(value: string | null): BrowserKind {
  const browser = (value ?? process.env['CORPUS_CHECK_BROWSER'] ?? 'chrome').toLowerCase()
  if (browser !== 'chrome' && browser !== 'safari') {
    throw new Error(`Unsupported browser ${browser}; expected chrome or safari`)
  }
  return browser
}

function parseOptionalNumberFlag(name: string): number | null {
  const raw = parseStringFlag(name)
  if (raw === null) return null
  const parsed = Number.parseInt(raw, 10)
  if (!Number.isFinite(parsed)) {
    throw new Error(`Invalid value for --${name}: ${raw}`)
  }
  return parsed
}

function hasFlag(name: string): boolean {
  return process.argv.includes(`--${name}`)
}

View on GitHub (pinned to ac49b09b7d)

Solutions

  1. Pass exactly `--browser=chrome` or `--browser=safari` (no whitespace, no variants).
  2. Unset or correct `CORPUS_CHECK_BROWSER` in your environment if a global export is leaking in.
  3. If you genuinely need Firefox corpus coverage, that is a feature gap — use the accuracy sweep or extend parseBrowser's allowlist and the corpus page's browser branches.

Example fix

// before
CORPUS_CHECK_BROWSER=firefox bun run scripts/corpus-check.ts --id=ja-kumo-no-ito
// after
bun run scripts/corpus-check.ts --id=ja-kumo-no-ito --browser=safari
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_CORPUS_BROWSERS = new Set(['chrome', 'safari'])
function normalizeBrowser(raw: string | null, env: string | undefined): 'chrome' | 'safari' {
  const value = (raw ?? env ?? 'chrome').trim().toLowerCase()
  if (!ALLOWED_CORPUS_BROWSERS.has(value)) {
    throw new Error(`Unsupported browser ${value}; expected one of ${[...ALLOWED_CORPUS_BROWSERS].join(', ')}`)
  }
  return value as 'chrome' | 'safari'
}

Type guard

function isCorpusBrowser(value: string): value is 'chrome' | 'safari' {
  return value === 'chrome' || value === 'safari'
}

Prevention

When it happens

Trigger: parseBrowser(value) sees a string that is not 'chrome' or 'safari' after lowercasing. Triggers on `--browser=firefox`, `--browser=Chrome ` (trailing space survives lowercasing — 'chrome ' !== 'chrome'), `--browser=webkit`, `--browser=canary`, or `CORPUS_CHECK_BROWSER=firefox` exported in the shell.

Common situations: Assuming corpus-check accepts Firefox because the wider browser-automation stack does (BrowserKind includes 'firefox'); exporting CORPUS_CHECK_BROWSER globally for a different script and forgetting it; passing a Chrome variant name (canary, chromium) expecting it to map to chrome; whitespace from shell quoting (`--browser="chrome "`).

Related errors


AI-assisted analysis of chenglou/pretext@ac49b09b7d (2026-08-12). Data as JSON: /api/errors/027dcf9bffd3eaf4. Report an issue: GitHub.