chenglou/pretext · error · Error
Unsupported bidi class ${raw}
Error message
Unsupported bidi class ${raw} What it means
The derived file contains a bidi class abbreviation the generator does not model. Recognized inputs: the 14 short codes (L,R,AL,AN,EN,ES,ET,CS,ON,BN,B,S,WS,NSM), their long forms (e.g. `Arabic_Letter`), and the formatting/isolate controls (LRE,LRO,RLE,RLO,PDF,LRI,RLI,FSI,PDI) which project onto BN. Anything else throws.
Source
Thrown at scripts/generate-bidi-data.ts:85
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$/)
if (versionMatch === null || versionMatch === undefined) {
throw new Error('Could not determine Unicode version from DerivedBidiClass header')
}
const unicodeVersion = versionMatch[1]!
const bidiCodes = new Uint8Array(0x110000)
bidiCodes.fill(generatedTypeToCode.get('L')!)
for (let i = 0; i < sourceLines.length; i++) {
const rawLine = sourceLines[i]!
let rangeText: string | null = null
let typeText: string | null = nullView on GitHub (pinned to ac49b09b7d)
Solutions
- If the class is a new formatting/isolate control, add it to `bnProjectedTypes` so it projects onto BN.
- If it is a genuine new resolved class, extend `GENERATED_TYPES`, `longBidiNames`, and the generated type union — but first confirm the rich bidi helper actually needs it.
- Otherwise re-download a clean DerivedBidiClass file; a stray token can masquerade as a class.
Example fix
// before: a new isolate control (hypothetical 'RIN') is unsupported const bnProjectedTypes = new Set(['LRE','LRO','RLE','RLO','PDF','LRI','RLI','FSI','PDI']) // after: project the new control onto BN const bnProjectedTypes = new Set(['LRE','LRO','RLE','RLO','PDF','LRI','RLI','FSI','PDI','RIN'])
Defensive patterns
Strategy: validation
Validate before calling
const KNOWN = new Set([...GENERATED_TYPES, ...longBidiNames.keys(), ...bnProjectedTypes])
const unknown = new Set<string>()
for (const line of sourceLines) {
const m = line.match(/;\s*([A-Za-z_]+)/)
if (m && !KNOWN.has(m[1])) unknown.add(m[1])
}
if (unknown.size > 0) {
console.error(`Unmodeled bidi classes: ${[...unknown].join(', ')}`)
process.exit(1)
} Type guard
const isRecognizedBidiClass = (raw: string): boolean => generatedTypeToCode.has(raw as GeneratedBidiType) || bnProjectedTypes.has(raw) || longBidiNames.has(raw)
Prevention
- After a Unicode upgrade, scan the derived file for classes outside the recognized set before generating.
- Prefer projecting new formatting/isolate controls onto BN via bnProjectedTypes rather than expanding the resolved type union.
- Only extend GENERATED_TYPES/longBidiNames if the rich bidi helper genuinely needs a new resolved class.
When it happens
Trigger: A newer Unicode version introduces or surfaces a bidi class not in the projection set, or the source file carries an unexpected long name.
Common situations: Upgrading the bundled DerivedBidiClass to a new Unicode version without updating the generator's class tables.
Related errors
- Invalid code point range: ${raw}
- Invalid widths parameter: ${raw}
- Invalid ACCURACY_CHECK_PORT: ${requestedPortRaw}
- Invalid value for --${name}: ${raw}
- Unsupported browser ${browser}; expected chrome or safari
AI-assisted analysis of chenglou/pretext@ac49b09b7d (2026-08-12).
Data as JSON: /api/errors/913710d6a41896c2.
Report an issue: GitHub.