{"record":{"id":"2f372b0356afe9a8","repo":"mozilla/pdf.js","slug":"end-of-file-inside-dictionary","errorCode":null,"errorMessage":"End of file inside dictionary.","messagePattern":"End of file inside dictionary\\.","errorType":"exception","errorClass":"ParserEOFException","httpStatus":null,"severity":"error","filePath":"src/core/parser.js","lineNumber":162,"sourceCode":"          while (!isCmd(this.buf1, \">>\") && this.buf1 !== EOF) {\n            if (!(this.buf1 instanceof Name)) {\n              info(\"Malformed dictionary: key must be a name object\");\n              this.shift();\n              continue;\n            }\n\n            const key = this.buf1.name;\n            this.shift();\n            if (this.buf1 === EOF) {\n              break;\n            }\n            dict.set(key, this.getObj(cipherTransform));\n          }\n          if (this.buf1 === EOF) {\n            if (this.recoveryMode) {\n              return dict;\n            }\n            throw new ParserEOFException(\"End of file inside dictionary.\");\n          }\n\n          // Stream objects are not allowed inside content streams or\n          // object streams.\n          if (isCmd(this.buf2, \"stream\")) {\n            return this.allowStreams\n              ? this.makeStream(dict, cipherTransform)\n              : dict;\n          }\n          this.shift();\n          return dict;\n        default: // simple object\n          return buf1;\n      }\n    }\n\n    if (Number.isInteger(buf1)) {\n      // indirect reference or integer","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/parser.js#L144-L180","documentation":"Thrown as a ParserEOFException by Parser.getObj() while collecting dictionary key/value pairs. The loop reads entries until '>>' or EOF; if EOF arrives first the dictionary is unterminated. As with arrays, recoveryMode returns the partial dict instead of throwing.","triggerScenarios":"getObj() handles a '<<' command and loops; this.buf1 becomes EOF before '>>'. The dictionary stream was truncated or the closing '>>' is missing. Fires after the loop's EOF break when not in recoveryMode.","commonSituations":"Truncated PDF where an object dictionary is cut off, corruption that damaged the '>>' delimiter, or a stream whose /Length was wrong causing the parser to lose position. Very common symptom of incomplete downloads or damaged object streams.","solutions":["Verify the PDF is fully downloaded (check file size, re-fetch).","If a specific object is implicated, inspect it with qpdf --qdf to linearize and locate the truncation.","Let PDF.js retry in recoveryMode; if it still fails, rebuild the PDF with qpdf --fix or Ghostscript.","Catch ParserEOFException during PDFDocumentLoadingTask to present a graceful error."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await pdfjsLib.getDocument({ data }).promise;\n} catch (e) {\n  if (e.name === 'ParserEOFException') { /* truncated dict, attempt recovery */ }\n  else throw e;\n}","preventionTips":["Verify the PDF is complete and not truncated.","Use qpdf --check or --fix to validate/repair dictionaries.","Catch ParserEOFException at document load to degrade gracefully."],"tags":["pdf","parser","corrupt-data","truncation","structure"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}