chenglou/pretext · error · Error

Invalid widths parameter: ${raw}

Error message

Invalid widths parameter: ${raw}

What it means

Thrown by parseWidthList() while parsing the ?widths= URL query parameter on the corpus page. The function splits the raw value on commas, trims each token, parses each with Number.parseInt, and keeps only finite results; if every token fails to parse to a finite integer it throws. This runs at module top-level (corpus.ts:225), so it aborts page initialization before any corpus loads. An absent parameter returns null and does NOT throw — only a present-but-empty-or-non-numeric value does.

Source

Thrown at pages/corpus.ts:273

const diagnosticGraphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' })

let corpusList: CorpusMeta[] = []
let currentMeta: CorpusMeta | null = null
let currentText = ''
let currentPrepared: PreparedTextWithSegments | null = null
let currentSliceStart: number | null = null
let currentSliceEnd: number | null = null

function parseWidthList(raw: string | null): number[] | null {
  if (raw === null) return null

  const widths = raw
    .split(',')
    .map(part => Number.parseInt(part.trim(), 10))
    .filter(width => Number.isFinite(width))

  if (widths.length === 0) {
    throw new Error(`Invalid widths parameter: ${raw}`)
  }

  return [...new Set(widths)]
}

function withRequestId<T extends CorpusReport>(report: T): CorpusReport {
  return requestId === undefined ? report : { ...report, requestId }
}

function toNavigationReport(report: CorpusReport): CorpusReport {
  if (report.rows === undefined) return report
  const { rows: _rows, ...navigationReport } = report
  return navigationReport
}

function getEnvironmentFingerprint(): EnvironmentFingerprint {
  return {
    userAgent: navigator.userAgent,

View on GitHub (pinned to ac49b09b7d)

Solutions

  1. Remove or fix the ?widths= parameter in the URL so it contains at least one integer (e.g. ?widths=300,400,500).
  2. If you do not need a sweep, drop the widths param entirely — parseWidthList receives null and returns null, and the page falls back to a single width.
  3. If a script is generating the URL, coerce each width to a finite integer and skip the param when the list is empty rather than emitting ?widths=.
  4. URL-encode the value only after validating it matches /^\d+(,\d+)*$/.

Example fix

// before
const url = `/corpus?widths=${widthsParam}`

// after
const safeWidths = (widthsParam && /\d+(,\d+)*/.test(widthsParam)) ? widthsParam : ''
const url = `/corpus${safeWidths ? `?widths=${safeWidths}` : ''}`
Defensive patterns

Strategy: validation

Validate before calling

// Validate the widths query param before constructing the URL.
function buildWidthsParam(widths: number[] | null | undefined): string {
  if (widths === null || widths === undefined) return ''
  const clean = widths.filter(w => Number.isInteger(w) && w > 0)
  return clean.length > 0 ? `?widths=${clean.join(',')}` : ''
}

Type guard

// Reject anything that would yield zero finite integers after split/parse.
function isValidWidthsParam(raw: string): boolean {
  if (raw.length === 0) return false
  return raw.split(',').every(part => /^\d+$/.test(part.trim())) &&
    raw.split(',').length > 0
}

Try / catch

// parseWidthList runs at module top-level and cannot be try/catch'd by the page.
// Validate the URL before navigation instead:
const widthsRaw = new URLSearchParams(location.search).get('widths')
if (widthsRaw !== null && !isValidWidthsParam(widthsRaw)) {
  // strip the bad param and reload, or show an error state
  const clean = new URLSearchParams(location.search)
  clean.delete('widths')
  history.replaceState(null, '', `?${clean.toString()}`)
}

Prevention

When it happens

Trigger: Loading /corpus?widths= (empty value), /corpus?widths=abc, /corpus?widths=,,, (only separators), or /corpus?widths=foo,bar. Each token is individually parseInt'd; if none yield a finite number the guard trips. A mix like ?widths=abc,400 does not throw because 400 survives the filter.

Common situations: A bookmarked or hand-edited URL with a typo in the widths param; an automation harness constructing the widths query string from an empty/undefined variable; copying a URL fragment where the widths value got truncated. The parameter is only used to drive the multi-width sweep path (getRequestedSweepWidths), so misformed values block the sweep landing page.

Related errors


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