parallax/jsPDF · error · Error

Font is not stored as string-data in vFS, import fonts or re

Error message

Font is not stored as string-data in vFS, import fonts or remove declaration doc.addFont('${font.postScriptName}').

What it means

jsPDF keeps custom TTF fonts in an in-memory virtual file system (VFS) keyed by postScriptName. The ttfsupport 'addFont' handler retrieves the entry via getFileFromVFS/loadFile and requires it to be a string — either a raw binary string beginning with the TTF magic bytes \x00\x01\x00\x00, or a base64 string that the handler will atob-decode. If the stored value is not a string (undefined, null, ArrayBuffer, Uint8Array, number, object), typeof file !== 'string' is true and this error throws.

Source

Thrown at src/modules/ttfsupport.js:58

  };

  jsPDF.API.events.push([
    "addFont",
    function(data) {
      var file = undefined;
      var font = data.font;
      var instance = data.instance;
      if (font.isStandardFont) {
        return;
      }
      if (typeof instance !== "undefined") {
        if (instance.existsFileInVFS(font.postScriptName) === false) {
          file = instance.loadFile(font.postScriptName);
        } else {
          file = instance.getFileFromVFS(font.postScriptName);
        }
        if (typeof file !== "string") {
          throw new Error(
            "Font is not stored as string-data in vFS, import fonts or remove declaration doc.addFont('" +
              font.postScriptName +
              "')."
          );
        }
        addFont(font, file);
      } else {
        throw new Error(
          "Font does not exist in vFS, import fonts or remove declaration doc.addFont('" +
            font.postScriptName +
            "')."
        );
      }
    }
  ]); // end of adding event handler
})(jsPDF);

View on GitHub (pinned to a3930ce03a)

Solutions

  1. Register the font as a base64 string first: doc.addFileToVFS('MyFont.ttf', base64String); then doc.addFont('MyFont.ttf','MyFont','normal').
  2. If you only have binary, convert it to a base64 string before addFileToVFS (ArrayBuffer -> Uint8Array -> btoa(String.fromCharCode.apply(...))).
  3. Make sure the postScriptName/file key passed to addFont exactly matches the key registered in addFileToVFS.
  4. If the custom font is not actually needed, remove the doc.addFont declaration so the handler never runs for it.

Example fix

// before
doc.addFont('MyFont.ttf', 'MyFont', 'normal');   // no addFileToVFS -> file is undefined -> not a string

// after
var b64 = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
doc.addFileToVFS('MyFont.ttf', b64);
doc.addFont('MyFont.ttf', 'MyFont', 'normal');
Defensive patterns

Strategy: validation

Validate before calling

function registerFont(doc, fileName, postScriptName, id, style) {
  var b64 = fileName; // assume already base64 string
  if (typeof b64 !== 'string' || b64.length === 0) {
    throw new TypeError('Font data for ' + postScriptName + ' must be a non-empty base64/binary string');
  }
  doc.addFileToVFS(fileName, b64);
  // sanity: VFS now holds a string for this key
  if (typeof doc.getFileFromVFS(postScriptName) !== 'string' && typeof doc.getFileFromVFS(fileName) !== 'string') {
    throw new Error('VFS did not store a string for ' + postScriptName);
  }
  doc.addFont(postScriptName, id, style);
}

Type guard

const isVfsStringFile = (file) => typeof file === 'string' && file.length > 0;
// usage: if (!isVfsStringFile(doc.getFileFromVFS(postScriptName))) { /* re-import font as base64 string */ }

Try / catch

try {
  doc.addFont('MyFont.ttf', 'MyFont', 'normal');
} catch (e) {
  if (/Font is not stored as string-data in vFS/.test(e.message)) {
    console.error('Font not in VFS as string — re-register via addFileToVFS with a base64 string:', e.message);
    // doc.addFileToVFS('MyFont.ttf', correctedBase64); doc.addFont(...);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling doc.addFont('MyFont.ttf','MyFont','normal') without a prior doc.addFileToVFS('MyFont.ttf', base64String); registering the VFS entry with a non-string such as an ArrayBuffer or Uint8Array obtained from fetch().arrayBuffer(); the postScriptName key in addFont not matching the key used in addFileToVFS so getFileFromVFS returns undefined.

Common situations: Forgetting the addFileToVFS step entirely; using a font-loader/fetch pipeline that yields a typed array and storing that directly instead of a base64 string; a VFS entry getting overwritten with a non-string by another plugin; version differences in how font binaries are expected to be supplied.

Related errors


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