{"record":{"id":"3e6b6236692c535f","repo":"mozilla/pdf.js","slug":"truetype-collection-font-must-contain-a-name-tab","errorCode":null,"errorMessage":"TrueType Collection font must contain a \"name\" table.","messagePattern":"TrueType Collection font must contain a \"name\" table\\.","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/fonts.js","lineNumber":1555,"sourceCode":"          return header;\n      }\n      throw new FormatError(\n        `Invalid TrueType Collection majorVersion: ${majorVersion}.`\n      );\n    }\n\n    function readTrueTypeCollectionData(ttc, fontName) {\n      const { numFonts, offsetTable } = readTrueTypeCollectionHeader(ttc);\n      const fontNameParts = fontName.split(\"+\");\n      let fallbackData;\n\n      for (let i = 0; i < numFonts; i++) {\n        ttc.pos = (ttc.start || 0) + offsetTable[i];\n        const potentialHeader = readOpenTypeHeader(ttc);\n        const potentialTables = readTables(ttc, potentialHeader.numTables);\n\n        if (!potentialTables.name) {\n          throw new FormatError(\n            'TrueType Collection font must contain a \"name\" table.'\n          );\n        }\n        const [nameTable] = readNameTable(potentialTables.name);\n\n        for (const nameArr of nameTable) {\n          for (const entry of nameArr) {\n            const nameEntry = entry?.replaceAll(/\\s/g, \"\");\n            if (!nameEntry) {\n              continue;\n            }\n            if (nameEntry === fontName) {\n              return {\n                header: potentialHeader,\n                tables: potentialTables,\n              };\n            }\n            if (fontNameParts.length < 2) {","sourceCodeStart":1537,"sourceCodeEnd":1573,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/fonts.js#L1537-L1573","documentation":"Thrown by readTrueTypeCollectionData() when iterating over sub-fonts in a TrueType Collection and one of the member fonts lacks a 'name' table. The 'name' table is mandatory in OpenType/TrueType — it carries the font's human-readable names used for matching the requested fontName.","triggerScenarios":"For each member font i in the TTC, readTables() returns potentialTables, and potentialTables.name is falsy. This triggers an immediate throw for that member font before name matching can occur.","commonSituations":"A TTC containing a corrupt, truncated, or stripped member font where the 'name' table was removed or never written. TTCs assembled by non-standard tools that omit mandatory tables. A TTC where one sub-font's offset table points to garbage data.","solutions":["Rebuild the TTC with fonttools TTCollection, which ensures all member fonts have complete tables.","Remove the corrupt member font from the collection if it is not the one needed.","Extract the specific font you need with TTFont('file.ttc', fontNumber=N) and embed it standalone.","Run ots-sanitize on each member font to identify structural deficiencies."],"exampleFix":"# extract the valid member font, drop the corrupt one\nfrom fontTools import ttLib\n\nfor i in range(10):\n    try:\n        f = ttLib.TTFont('broken.ttc', fontNumber=i)\n        if 'name' in f:\n            f.save(f'font_{i}.ttf')\n            break\n    except Exception:\n        continue","handlingStrategy":"validation","validationCode":"// Server-side: verify all TTC member fonts have a 'name' table\n// from fontTools import ttLib\n// ttc = ttLib.TTCollection('fonts.ttc')\n// for i, font in enumerate(ttc.fonts):\n//     if 'name' not in font:\n//         print(f'Member font {i} is missing name table')\nfunction ttcMembersHaveNameTable(buffer) {\n  // Parse TTC offset table, iterate members, check for 'name' tag in each\n  // Requires a minimal SFNT/TTC parser; use fonttools server-side instead.\n}","typeGuard":null,"tryCatchPattern":"try {\n  await page.render(renderParams).promise;\n} catch (err) {\n  if (err.message?.includes('must contain a \"name\" table')) {\n    console.error('TTC member font is missing mandatory name table; rebuild the TTC.');\n  } else { throw err; }\n}","preventionTips":["Build TTCs with fonttools TTCollection, which enforces mandatory tables on all members.","Run ots-sanitize on each TTC member font.","Remove corrupt member fonts from TTCs before embedding."],"tags":["font","ttc","name-table","truetype-collection","format-error"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}