{"record":{"id":"5240f085aff9771f","repo":"mozilla/pdf.js","slug":"page-dictionary-kids-object-is-not-an-array","errorCode":null,"errorMessage":"Page dictionary kids object is not an array.","messagePattern":"Page dictionary kids object is not an array\\.","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/catalog.js","lineNumber":1423,"sourceCode":"        kids = await xref.fetchAsync(kids);\n      }\n      if (!Array.isArray(kids)) {\n        // Prevent errors in corrupt PDF documents that violate the\n        // specification by *inlining* Page dicts directly in the Kids\n        // array, rather than using indirect objects (fixes issue9540.pdf).\n        let type = currentNode.getRaw(\"Type\");\n        if (type instanceof Ref) {\n          type = await xref.fetchAsync(type);\n        }\n        if (isName(type, \"Page\") || !currentNode.has(\"Kids\")) {\n          if (currentPageIndex === pageIndex) {\n            return [currentNode, null];\n          }\n          currentPageIndex++;\n          continue;\n        }\n\n        throw new FormatError(\"Page dictionary kids object is not an array.\");\n      }\n\n      // Always check all `Kids` nodes, to avoid getting stuck in an empty\n      // node further down in the tree (see issue5644.pdf, issue8088.pdf),\n      // and to ensure that we actually find the correct `Page` dict.\n      for (let last = kids.length - 1; last >= 0; last--) {\n        const lastKid = kids[last];\n        nodesToVisit.push(lastKid);\n\n        // Launch all requests in parallel so we don't wait for each one in turn\n        // when looking for a page near the end, if all the pages are top level.\n        if (\n          currentNode === this.toplevelPagesDict &&\n          lastKid instanceof Ref &&\n          !pageDictCache.has(lastKid)\n        ) {\n          pageDictCache.put(lastKid, xref.fetchAsync(lastKid));\n        }","sourceCodeStart":1405,"sourceCodeEnd":1441,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/catalog.js#L1405-L1441","documentation":"Thrown in Catalog.getPageDict() (catalog.js:1423) when a /Pages dictionary's /Kids entry is not an array, after the inline-Page recovery path (handling producers that inline Page dicts directly in Kids) also fails. /Kids must be an array of references; a non-array with a present /Kids that is not /Page-typed is invalid.","triggerScenarios":"currentNode.getRaw('Kids') (after ref-fetch) is not an Array, and the node is not a /Page (isName(type,'Page') false) and still has a Kids key, so the recovery branch at line 1415 does not apply. Reached during getPage(n).","commonSituations":"A producer that wrote /Kids as a single dict or scalar instead of an array; a corrupt page tree where /Kids was overwritten; an edited PDF. Known-corrupt specimens are partially tolerated (issue9540.pdf) before this throws.","solutions":["Repair with 'mutool clean' or 'qpdf --linearize' to normalise /Kids into an array of refs.","Run 'qpdf --check' to detect the malformed /Kids before runtime.","Enable recovery/ignoreErrors so PDF.js can skip the broken subtree.","If producing PDFs, always emit /Kids as a PDF array of indirect references."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Cannot cheaply validate /Kids shape pre-load via public API.\n// Repair: qpdf --linearize in.pdf out.pdf","typeGuard":null,"tryCatchPattern":"try {\n  const page = await pdf.getPage(n);\n} catch (err) {\n  if (/kids object is not an array/i.test(err?.message)) {\n    console.warn('/Kids is not an array; document needs repair', err);\n  } else throw err;\n}","preventionTips":["Always write /Kids as a PDF array of indirect references when producing PDFs.","Repair malformed trees with qpdf/mutool.","Run 'qpdf --check' to catch the bad /Kids early.","Use ignoreErrors/recovery for tolerant loading."],"tags":["pdf-structure","pages-tree","corrupt-pdf","page-retrieval"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}