mozilla/pdf.js · error · Error
getTextContent - ignoring circular reference: ${objId}
Error message
getTextContent - ignoring circular reference: ${objId} What it means
Thrown at the start of getTextContent when the stream's objId already appears in prevRefs. It is the text-extraction equivalent of the getOperatorList anti-recursion guard: a Form XObject re-entered during text extraction would otherwise loop. Like [85], this is a bare throw at method entry and is NOT suppressed by ignoreErrors.
Source
Thrown at src/core/evaluator.js:2417
disableNormalization = false,
keepWhiteSpace = false,
prevRefs = null,
intersector = null,
}) {
if (stream.isAsync) {
const bytes = await stream.asyncGetBytes();
if (bytes) {
stream = new Stream(bytes, 0, bytes.length, stream.dict);
}
}
sink ??= textSinkWrapper(null);
const objId = stream.dict?.objId;
const seenRefs = new RefSet(prevRefs);
if (objId) {
if (prevRefs?.has(objId)) {
throw new Error(
`getTextContent - ignoring circular reference: ${objId}`
);
}
seenRefs.put(objId);
}
// Ensure that `resources`/`stateManager` is correctly initialized,
// even if the provided parameter is e.g. `null`.
resources ||= Dict.empty;
stateManager ||= new StateManager(new TextState());
if (includeMarkedContent) {
markedContentData ||= { level: 0 };
}
const textContent = {
items: [],
styles: Object.create(null),
lang,View on GitHub (pinned to 5903d58d58)
Solutions
- Wrap page.getTextContent() in try/catch and fall back (e.g. empty text or skip search) since ignoreErrors will not help here.
- Repair the PDF to break the XObject cycle.
- Upgrade PDF.js for hardened cycle detection.
Example fix
// before
const tc = await page.getTextContent(); // rejects on cycle
// after
let tc;
try {
tc = await page.getTextContent();
} catch (e) {
console.warn('Text extraction failed (circular XObject):', e.message);
tc = { items: [], styles: {} };
} Defensive patterns
Strategy: try-catch
Try / catch
// ignoreErrors does NOT suppress this; catch at the getTextContent boundary.
let textContent;
try {
textContent = await page.getTextContent();
} catch (e) {
if (/circular reference/.test(e.message)) {
textContent = { items: [], styles: {} }; // graceful empty result
} else throw e;
} Prevention
- Never rely on ignoreErrors to cover cycle guards; it does not.
- Give every getTextContent call a top-level try/catch in search/copy features.
- Sanitize incoming PDFs to break XObject reference loops.
When it happens
Trigger: getTextContent traverses into a Form XObject whose stream chain re-enters a stream already on the ancestor path (cycle in the XObject reference graph).
Common situations: Malformed or malicious PDFs with cyclic Form XObject references; the symptom specifically affects text extraction / search rather than rendering.
Related errors
- getOperatorList - ignoring circular reference: ${objId}
- XObject must be referred to by name.
- XObject should be a stream
- XObject should have a Name subtype
- Unhandled XObject subtype ${type.name}
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/6ff5b0d3c0783020.
Report an issue: GitHub.