{"record":{"id":"e28a29fc65f157b8","repo":"mozilla/pdf.js","slug":"page-dictionary-kid-reference-points-to-wrong-type","errorCode":null,"errorMessage":"Page dictionary kid reference points to wrong type of object.","messagePattern":"Page dictionary kid reference points to wrong type of object\\.","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/catalog.js","lineNumber":1379,"sourceCode":"            // Help improve performance of the `getPageIndex` method.\n            if (!pageIndexCache.has(currentNode)) {\n              pageIndexCache.put(currentNode, currentPageIndex);\n            }\n\n            if (currentPageIndex === pageIndex) {\n              return [obj, currentNode];\n            }\n            currentPageIndex++;\n            continue;\n          }\n        }\n        nodesToVisit.push(obj);\n        continue;\n      }\n\n      // Must be a child page dictionary.\n      if (!(currentNode instanceof Dict)) {\n        throw new FormatError(\n          \"Page dictionary kid reference points to wrong type of object.\"\n        );\n      }\n      const { objId } = currentNode;\n\n      let count = currentNode.getRaw(\"Count\");\n      if (count instanceof Ref) {\n        count = await xref.fetchAsync(count);\n      }\n      if (Number.isInteger(count) && count >= 0) {\n        // Cache the Kids count, since it can reduce redundant lookups in\n        // documents where all nodes are found at *one* level of the tree.\n        if (objId && !pageKidsCountCache.has(objId)) {\n          pageKidsCountCache.put(objId, count);\n        }\n\n        // Skip nodes where the page can't be.\n        if (currentPageIndex + count <= pageIndex) {","sourceCodeStart":1361,"sourceCodeEnd":1397,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/catalog.js#L1361-L1397","documentation":"Thrown in Catalog.getPageDict() (catalog.js:1379) when a node popped off nodesToVisit is neither a Ref nor a Dict. Kids entries should be Refs (resolving to Dicts); after a Ref resolves to a non-Dict it is pushed back and re-examined here. If that object is still not a Dict, the kid reference is the wrong type.","triggerScenarios":"A Kids array entry is a non-Ref primitive (number/string/null) and is not a Dict, OR a Ref resolves to a non-dictionary object (stream, array, scalar). Reached during pdfDocument.getPage(n) traversal.","commonSituations":"Corrupt PDF with a malformed /Kids array containing scalar/null entries; a Ref pointing at the wrong (non-dict) object due to a shifted xref; a hand-edited page tree.","solutions":["Repair the PDF with qpdf/mutool to rebuild /Kids as proper indirect references to dictionaries.","Validate the page tree with 'qpdf --check' before relying on getPage().","Load with error recovery enabled and accept that the affected page may be unreachable.","If producing PDFs, ensure every /Kids entry is an indirect reference to a /Page or /Pages dictionary."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-validation requires walking the page tree, which is the failing operation.\n// Repair the PDF instead: mutool clean in.pdf out.pdf","typeGuard":null,"tryCatchPattern":"try {\n  const page = await pdf.getPage(n);\n} catch (err) {\n  if (/kid reference points to wrong type/i.test(err?.message)) {\n    console.warn('Malformed /Kids entry; repair the PDF', err);\n  } else throw err;\n}","preventionTips":["Ensure every /Kids entry is an indirect reference to a dictionary when producing PDFs.","Repair malformed page trees with qpdf/mutool.","Run 'qpdf --check' on inputs.","Enable recovery/ignoreErrors for resilient loading."],"tags":["pdf-structure","pages-tree","corrupt-pdf","page-retrieval","xref"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}