{"record":{"id":"6a1922c4d4f2c137","repo":"mozilla/pdf.js","slug":"descendant-fonts-are-not-specified","errorCode":null,"errorMessage":"Descendant fonts are not specified","messagePattern":"Descendant fonts are not specified","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/evaluator.js","lineNumber":4304,"sourceCode":"  }\n\n  preEvaluateFont(dict) {\n    const baseDict = dict;\n    let type = dict.get(\"Subtype\");\n    if (!(type instanceof Name)) {\n      throw new FormatError(\"invalid font Subtype\");\n    }\n\n    let composite = false;\n    let hash;\n    if (type.name === \"Type0\") {\n      // If font is a composite\n      //  - get the descendant font\n      //  - set the type according to the descendant font\n      //  - get the FontDescriptor from the descendant font\n      const df = dict.get(\"DescendantFonts\");\n      if (!df) {\n        throw new FormatError(\"Descendant fonts are not specified\");\n      }\n      dict = Array.isArray(df) ? this.xref.fetchIfRef(df[0]) : df;\n\n      if (!(dict instanceof Dict)) {\n        throw new FormatError(\"Descendant font is not a dictionary.\");\n      }\n      type = dict.get(\"Subtype\");\n      if (!(type instanceof Name)) {\n        throw new FormatError(\"invalid font Subtype\");\n      }\n      composite = true;\n    }\n\n    let firstChar = dict.get(\"FirstChar\");\n    if (!Number.isInteger(firstChar)) {\n      firstChar = 0;\n    }\n    let lastChar = dict.get(\"LastChar\");","sourceCodeStart":4286,"sourceCodeEnd":4322,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/evaluator.js#L4286-L4322","documentation":"Thrown by preEvaluateFont() when a Type0 (composite) font dictionary has no /DescendantFonts entry. The PDF spec requires Type0 fonts to declare a /DescendantFonts array referencing exactly one CIDFont; without it the font cannot be loaded because the actual glyph data lives in the descendant. This guard precedes the array-index access that would otherwise crash.","triggerScenarios":"A font dictionary with /Subtype /Type0 whose /DescendantFonts is absent, null, or falsy. Fires during font pre-evaluation for any page that references such a font.","commonSituations":"PDF generators that build Type0 wrappers incompletely, PDFs that were truncated mid-stream, or font dictionaries damaged by a faulty linearization/optimization pass. Common in PDFs that were machine-modified to embed subsets.","solutions":["Re-save the PDF through Acrobat 'Save As' or Ghostscript to rebuild the Type0 structure.","If authoring, verify your PDF library writes /DescendantFonts as a one-element array of indirect references.","Isolate failing pages with stopAtErrors: true and per-page try/catch.","If the PDF renders in other viewers, report it to PDF.js with the file for fallback-heuristic improvement."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await page.render({ canvasContext, viewport });\n} catch (e) {\n  if (e.name === 'FormatError' && /Descendant fonts are not specified/.test(e.message)) {\n    console.warn('Type0 font missing DescendantFonts, skipping');\n  } else throw e;\n}","preventionTips":["When authoring Type0 fonts, always include /DescendantFonts as a one-element array of indirect references.","Repair PDFs with Ghostscript to rebuild the Type0/CIDFont structure.","Screen PDFs with qpdf --check for missing required font entries."],"tags":["pdf","font","type0","descendant-fonts","format-error"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}