parallax/jsPDF · error · Error

Don't know what to do with value type ${typeof value}.

Error message

Don't know what to do with value type ${typeof value}.

What it means

The internal font-metrics compress() walker only knows how to encode two value types: numbers (hex-encoded) and objects (recursed). Any other type — string, boolean, function, symbol, or null/undefined as a non-object — falls to the else branch and throws 'Don't know what to do with value type <typeof>.' This is part of jsPDF's private __fontmetrics__ compression used to serialize font metric tables.

Source

Thrown at src/modules/standard_fonts_metrics.js:98

      }

      if (typeof value == "number") {
        if (value < 0) {
          valuestring = hex(value).slice(3);
          numberprefix = "-";
        } else {
          valuestring = hex(value).slice(2);
          numberprefix = "";
        }
        valuestring =
          numberprefix +
          valuestring.slice(0, -1) +
          mappingCompress[valuestring.slice(-1)];
      } else {
        if (typeof value === "object") {
          valuestring = compress(value);
        } else {
          throw new Error(
            "Don't know what to do with value type " + typeof value + "."
          );
        }
      }
      vals.push(keystring + valuestring);
    }
    vals.push("}");
    return vals.join("");
  });

  /**
   * Uncompresses data compressed into custom, base16-like format.
   *
   * @public
   * @function
   * @param
   * @returns {Type}
   */

View on GitHub (pinned to a3930ce03a)

Solutions

  1. Ensure every leaf value passed to compress() is a number or a nested object of numbers.
  2. Strip or convert string/boolean leaves before compressing.
  3. Prefer using jsPDF's standard font APIs (addFont with .ttf) rather than calling compress() directly.
  4. Validate the metric tree shape (all leaves numeric) before invoking compress.

Example fix

// before
API.__fontmetrics__.compress({ width: 500, name: 'Roboto' }); // 'Roboto' is a string -> throws [118]

// after
API.__fontmetrics__.compress({ width: 500 }); // drop non-numeric metadata
Defensive patterns

Strategy: validation

Validate before calling

function metricsTreeIsCompressible(obj) {
  for (const k in obj) {
    const v = obj[k];
    if (typeof v === 'number') continue;
    if (v && typeof v === 'object') { if (!metricsTreeIsCompressible(v)) return false; }
    else return false; // string, boolean, function, null, undefined
  }
  return true;
}

Type guard

function isCompressibleMetrics(value) {
  if (typeof value === 'number') return true;
  if (value && typeof value === 'object') {
    return Object.values(value).every(isCompressibleMetrics);
  }
  return false;
}

Try / catch

try {
  compressed = API.__fontmetrics__.compress(metrics);
} catch (e) {
  if (/Don't know what to do with value type/.test(e.message)) {
    // strip non-numeric leaves and retry, or use standard addFont instead
  } else throw e;
}

Prevention

When it happens

Trigger: Calling API.__fontmetrics__.compress() (or feeding custom font-metric data into it) with a structure containing string/boolean/function/null leaf values instead of numbers or nested objects. Most commonly hit by third-party or hand-built metric tables fed into the compress path.

Common situations: Injecting custom font metrics that include string annotations or boolean flags; feeding a parsed/mutated metrics object whose leaves are not numbers; version skew where a metrics schema added non-numeric fields.

Related errors


AI-assisted analysis of parallax/jsPDF@a3930ce03a (2026-08-13). Data as JSON: /api/errors/5a3b49af59f380c2. Report an issue: GitHub.