{"record":{"id":"ba825fbdd747b71a","repo":"mozilla/pdf.js","slug":"invalid-object-number-in-the-objstm-stream-num","errorCode":null,"errorMessage":"invalid object number in the ObjStm stream: ${num}","messagePattern":"invalid object number in the ObjStm stream: (.+?)","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/xref.js","lineNumber":979,"sourceCode":"      throw new FormatError(\"bad ObjStm stream\");\n    }\n    const first = stream.dict.get(\"First\");\n    const n = stream.dict.get(\"N\");\n    if (!Number.isInteger(first) || !Number.isInteger(n)) {\n      throw new FormatError(\"invalid first and n parameters for ObjStm stream\");\n    }\n    let parser = new Parser({\n      lexer: new Lexer(stream),\n      xref: this,\n      allowStreams: true,\n    });\n    const nums = new Array(n);\n    const offsets = new Array(n);\n    // read the object numbers to populate cache\n    for (let i = 0; i < n; ++i) {\n      const num = parser.getObj();\n      if (!Number.isInteger(num)) {\n        throw new FormatError(\n          `invalid object number in the ObjStm stream: ${num}`\n        );\n      }\n      const offset = parser.getObj();\n      if (!Number.isInteger(offset)) {\n        throw new FormatError(\n          `invalid object offset in the ObjStm stream: ${offset}`\n        );\n      }\n      nums[i] = num;\n\n      // The entry in the xref table is the object number followed by the index.\n      // So if index (gen number) is not the same as the index (i), we fix it\n      // (fixes bug 1978317).\n      const entry = this.getEntry(num);\n      if (entry?.offset === tableOffset && entry.gen !== i) {\n        entry.gen = i;\n      }","sourceCodeStart":961,"sourceCodeEnd":997,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/xref.js#L961-L997","documentation":"A FormatError raised while parsing the N header pairs of an Object Stream: the value read for an object number is not an integer. The ObjStm body begins with N pairs of (objectNumber, offset); a non-integer here means the stream content is truncated, reordered, or corrupt past the dict. The interpolated value is included in the message.","triggerScenarios":"ObjStm content stream is truncated mid-header; encryption/decryption misalignment shifted tokens; a FlateDecode error produced garbage; offsets written by a buggy writer.","commonSituations":"Partially downloaded files where the ObjStm stream is cut off; corrupt deflate streams; PDFs from non-conformant generators.","solutions":["Re-download the complete file (truncation is the most common cause).","Repair with qpdf or mutool to rebuild object streams.","Catch FormatError at the page/object boundary and skip affected content.","If you control transport, verify Content-Length matches before handoff."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const page = await doc.getPage(n);\n} catch (e) {\n  if (e instanceof pdfjsLib.FormatError) {\n    // log and skip; the ObjStm content is corrupt\n  }\n}","preventionTips":["Verify file integrity (size/hash) before loading.","Catch FormatError around page access and degrade gracefully.","Re-export or repair corrupt PDFs upstream."],"tags":["objstm","corruption","parsing","format-error"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}