mozilla/pdf.js · error · FormatError
unknown operator: ${v}
Error message
unknown operator: ${v} What it means
Thrown during CFF charstring interpretation when a single-byte value v is less than 32 but does not match any recognized Type 2 operator (1=hstem, 3-vstem, 4-vmoveto, ..., 31=hvcurveto). Values below 32 are reserved as operators in Type 2 charstrings; an unrecognized one means the charstring data is corrupt or uses an unsupported operator.
Source
Thrown at src/core/font_renderer.js:716
y = yb + stack.shift();
x = xb + (stack.length === 1 ? stack.shift() : 0);
bezierCurveTo(xa, ya, xb, yb, x, y);
if (stack.length === 0) {
break;
}
xa = x;
ya = y + stack.shift();
xb = xa + stack.shift();
yb = ya + stack.shift();
x = xb + stack.shift();
y = yb + (stack.length === 1 ? stack.shift() : 0);
bezierCurveTo(xa, ya, xb, yb, x, y);
}
break;
default:
if (v < 32) {
throw new FormatError(`unknown operator: ${v}`);
}
if (v < 247) {
stack.push(v - 139);
} else if (v < 251) {
stack.push((v - 247) * 256 + code[i++] + 108);
} else if (v < 255) {
stack.push(-(v - 251) * 256 - code[i++] - 108);
} else {
stack.push(view.getInt32(i) / 65536);
i += 4;
}
break;
}
if (stackClean) {
stack.length = 0;
}
}
}View on GitHub (pinned to 5903d58d58)
Solutions
- Obtain a clean copy of the font; round-trip it through fonttools (ttx export + recompile) to normalize charstrings.
- Replace the embedded CFF font in the PDF with a known-good version.
- If authoring CFF fonts, validate charstrings with fontTools.misc.psCharStrings or ots-sanitize before shipping.
- Update pdf.js to the latest version for improved operator coverage.
Example fix
# validate and repair CFF charstrings pip install fonttools brotli ttx broken.otf # decompile to XML ttx fixed.ttx # recompile — normalizes operators ots-sanitize fixed.otf # verify compliance
Defensive patterns
Strategy: try-catch
Try / catch
// The error is cached per-glyph in CompiledFont.#compiledGlyphs and
// re-thrown on subsequent getPath calls for the same glyph.
try {
await page.render(renderParams).promise;
} catch (err) {
if (err.message?.startsWith('unknown operator:') && !err.message.includes('12')) {
console.warn('Corrupt CFF charstring operator; glyph not rendered.');
} else { throw err; }
} Prevention
- Validate CFF fonts with ots-sanitize or fontbakery before embedding.
- Rebuild fonts with fonttools to normalize charstring bytecode.
- Keep PDF.js updated for improved operator coverage and error recovery.
When it happens
Trigger: compileGlyphImpl() reads a byte v < 32 from a CFF charstring that doesn't correspond to any implemented operator case in the switch statement. The default branch checks v < 32 and throws. This is distinct from bytes >= 32 which are number-encoding operators.
Common situations: Corrupt CFF charstring bytecode caused by truncation, byte corruption, or misaligned reads from earlier bad data. Fonts produced by buggy CFF compilers. Charstrings that use obsolete Type 1 operators not valid in Type 2. The error is cached per-glyph and re-thrown on subsequent getPath calls for the same glyph.
Related errors
- unknown operator: 12 ${v}
- unsupported cmap: ${format}
- Unicode ranges Bits > 123 are reserved for internal usage
- Required "maxp" table is not found
- "maxp" table has a wrong version number
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/201a5411b98a43c7.
Report an issue: GitHub.