mozilla/pdf.js · error · FormatError

Already tracking location of ${key}

Error message

Already tracking location of ${key}

What it means

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.

Source

Thrown at src/core/cff_parser.js:1448

  getFDIndex(glyphIndex) {
    return glyphIndex < 0 || glyphIndex >= this.fdSelect.length
      ? -1
      : this.fdSelect[glyphIndex];
  }
}

// Helper class to keep track of where an offset is within the data and helps
// filling in that offset once it's known.
class CFFOffsetTracker {
  offsets = Object.create(null);

  isTracking(key) {
    return key in this.offsets;
  }

  track(key, location) {
    if (key in this.offsets) {
      throw new FormatError(`Already tracking location of ${key}`);
    }
    this.offsets[key] = location;
  }

  offset(value) {
    for (const key in this.offsets) {
      this.offsets[key] += value;
    }
  }

  setEntryLocation(key, values, output) {
    if (!(key in this.offsets)) {
      throw new FormatError(`Not tracking location of ${key}`);
    }
    const data = output.data;
    const dataOffset = this.offsets[key];
    const size = 5;
    for (let i = 0, ii = values.length; i < ii; ++i) {

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Ensure offsetTracker.isTracking(key) is checked (and track skipped) before calling track, as compileDict already does.
  2. Report the issue to pdf.js with the offending font — this should be unreachable in shipped code.
  3. If patching, audit every track() call site to guarantee one-time tracking per key.

Example fix

// before
tracker.track('CharStrings', out.length); // throws on second call

// after
if (!tracker.isTracking('CharStrings')) {
  tracker.track('CharStrings', out.length);
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard track() with isTracking() before calling.
function safeTrack(tracker, key, location) {
  if (tracker.isTracking(key)) {
    return; // already tracked; skip
  }
  tracker.track(key, location);
}

Type guard

function shouldTrack(tracker, key) {
  return !tracker.isTracking(key);
}

Try / catch

try {
  tracker.track(key, location);
} catch (e) {
  // Already tracked; safe to ignore in idempotent flows.
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13). Data as JSON: /api/errors/fc9283ea0c1599cc. Report an issue: GitHub.