chenglou/pretext · error · Error

Invalid code point range: ${raw}

Error message

Invalid code point range: ${raw}

What it means

Thrown while parsing a hex code-point range line from `scripts/unicode/DerivedBidiClass-<version>.txt`. Fails if start/end aren't valid hex integers, start is negative, or end < start. Ranges look like `0041..005A` or a single `0041`.

Source

Thrown at scripts/generate-bidi-data.ts:73

  'RLE',
  'RLO',
  'PDF',
  'LRI',
  'RLI',
  'FSI',
  'PDI',
])

function formatHex(value: number): string {
  return `0x${value.toString(16).toUpperCase()}`
}

function parseCodePointRange(raw: string): { start: number, end: number } {
  const [startRaw, endRaw] = raw.split('..')
  const start = Number.parseInt(startRaw!, 16)
  const end = endRaw === undefined ? start : Number.parseInt(endRaw, 16)
  if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) {
    throw new Error(`Invalid code point range: ${raw}`)
  }
  return { start, end }
}

function simplifyBidiType(raw: string): GeneratedBidiType {
  if (generatedTypeToCode.has(raw as GeneratedBidiType)) return raw as GeneratedBidiType
  if (bnProjectedTypes.has(raw)) return 'BN'

  const longName = longBidiNames.get(raw)
  if (longName !== undefined) return longName

  throw new Error(`Unsupported bidi class ${raw}`)
}

function buildPayload(sourceText: string): GeneratedBidiPayload {
  const sourceLines = sourceText.split(/\r?\n/)
  const versionLine = sourceLines.find(line => line.startsWith('# DerivedBidiClass-'))
  const versionMatch = versionLine?.match(/^# DerivedBidiClass-(.+)\.txt$/)

View on GitHub (pinned to ac49b09b7d)

Solutions

  1. Re-download `DerivedBidiClass-<version>.txt` from the Unicode UCD; do not hand-edit it.
  2. If upgrading Unicode, confirm the file format is unchanged; the parser expects `HEX[..HEX] ; CLASS`.
  3. Inspect the `raw` value in the message — it pinpoints the offending line.

Example fix

// before: hand-edited range with a typo in the hex end
0530..053F ;  R   # ARMENIAN
// after: valid hex range (re-download from UCD)
0530..058F ;  R   # ARMENIAN
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check every range token in the derived file before generating
for (const line of sourceLines) {
  const m = line.match(/^([0-9A-Fa-f]+(?:\.\.[0-9A-Fa-f]+)?)/)
  if (!m) continue
  const [s, e] = m[1].split('..')
  const start = parseInt(s, 16), end = parseInt(e ?? s, 16)
  if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end < start) {
    console.error(`Bad range line: ${line}`)
    process.exit(1)
  }
}

Type guard

const isValidHexRange = (raw: string): boolean => {
  const m = raw.match(/^([0-9A-Fa-f]+)(?:\.\.([0-9A-Fa-f]+))?$/)
  if (!m) return false
  const start = parseInt(m[1], 16), end = parseInt(m[2] ?? m[1], 16)
  return Number.isInteger(start) && Number.isInteger(end) && start >= 0 && end >= start
}

Prevention

When it happens

Trigger: The bundled DerivedBidiClass file is replaced with one whose range column isn't well-formed hex, or the buildPayload regex lets a malformed line through to parseCodePointRange.

Common situations: Upgrading the Unicode source file to a version with a format change; hand-editing the derived file; pointing the script at a truncated or corrupted download.

Related errors


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