{"record":{"id":"fc9283ea0c1599cc","repo":"mozilla/pdf.js","slug":"already-tracking-location-of-key","errorCode":null,"errorMessage":"Already tracking location of ${key}","messagePattern":"Already tracking location of (.+?)","errorType":"exception","errorClass":"FormatError","httpStatus":null,"severity":"error","filePath":"src/core/cff_parser.js","lineNumber":1448,"sourceCode":"  getFDIndex(glyphIndex) {\n    return glyphIndex < 0 || glyphIndex >= this.fdSelect.length\n      ? -1\n      : this.fdSelect[glyphIndex];\n  }\n}\n\n// Helper class to keep track of where an offset is within the data and helps\n// filling in that offset once it's known.\nclass CFFOffsetTracker {\n  offsets = Object.create(null);\n\n  isTracking(key) {\n    return key in this.offsets;\n  }\n\n  track(key, location) {\n    if (key in this.offsets) {\n      throw new FormatError(`Already tracking location of ${key}`);\n    }\n    this.offsets[key] = location;\n  }\n\n  offset(value) {\n    for (const key in this.offsets) {\n      this.offsets[key] += value;\n    }\n  }\n\n  setEntryLocation(key, values, output) {\n    if (!(key in this.offsets)) {\n      throw new FormatError(`Not tracking location of ${key}`);\n    }\n    const data = output.data;\n    const dataOffset = this.offsets[key];\n    const size = 5;\n    for (let i = 0, ii = values.length; i < ii; ++i) {","sourceCodeStart":1430,"sourceCodeEnd":1466,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/cff_parser.js#L1430-L1466","documentation":"Thrown by CFFOffsetTracker.track when called twice for the same key. Each offset must be tracked exactly once during CFF compilation; tracking the same key twice violates the compiler's internal invariant and would corrupt offset bookkeeping.","triggerScenarios":"The CFF compiler calls offsetTracker.track(name, location) for a name already present in the offsets map. compileDict guards with isTracking before track, so this fires only if that guard is bypassed or another code path tracks the same key.","commonSituations":"A pdf.js internal bug where two compilation paths track the same offset name; a fork that manually calls track without checking isTracking; malformed font data that causes the same offset name to be emitted twice if a guard regressed.","solutions":["Ensure offsetTracker.isTracking(key) is checked (and track skipped) before calling track, as compileDict already does.","Report the issue to pdf.js with the offending font — this should be unreachable in shipped code.","If patching, audit every track() call site to guarantee one-time tracking per key."],"exampleFix":"// before\ntracker.track('CharStrings', out.length); // throws on second call\n\n// after\nif (!tracker.isTracking('CharStrings')) {\n  tracker.track('CharStrings', out.length);\n}","handlingStrategy":"validation","validationCode":"// Guard track() with isTracking() before calling.\nfunction safeTrack(tracker, key, location) {\n  if (tracker.isTracking(key)) {\n    return; // already tracked; skip\n  }\n  tracker.track(key, location);\n}","typeGuard":"function shouldTrack(tracker, key) {\n  return !tracker.isTracking(key);\n}","tryCatchPattern":"try {\n  tracker.track(key, location);\n} catch (e) {\n  // Already tracked; safe to ignore in idempotent flows.\n}","preventionTips":["Always check isTracking() before track() (compileDict already does).","Treat this error as an internal invariant bug; report with the offending font.","Ensure each offset name is tracked from exactly one code path."],"tags":["font","cff","cff-compiler","offset-tracker","internal-api","invariant"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}