parallax/jsPDF · error · Error

Character at position {position} of string '{text}' exceeds

Error message

Character at position {position} of string '{text}' exceeds 16bits. Cannot be encoded into UCS-2 BE

What it means

Thrown by the UCS-2 BE text encoder used when embedding Unicode strings into the PDF content stream. The loop walks each character, splits its code unit into high/low bytes, and guards against any code unit wider than 16 bits. In practice this guard is effectively unreachable: String.prototype.charCodeAt always returns a value in 0-65535, so (ch >> 8) >> 8 is always 0 for a normal JS string. It exists as a defensive assertion over the encoder's 16-bit assumption.

Source

Thrown at src/jspdf.js:2650

    // isUnicode may be set to false above. Hence the triple-equal to undefined
    while (isUnicode === undefined && i !== 0) {
      if (text.charCodeAt(i - 1) >> 8) {
        /* more than 255 */
        isUnicode = true;
      }
      i--;
    }
    if (!isUnicode) {
      return text;
    }

    newtext = flags.noBOM ? [] : [254, 255];
    for (i = 0, l = text.length; i < l; i++) {
      ch = text.charCodeAt(i);
      bch = ch >> 8; // divide by 256
      if (bch >> 8) {
        /* something left after dividing by 256 second time */
        throw new Error(
          "Character at position " +
            i +
            " of string '" +
            text +
            "' exceeds 16bits. Cannot be encoded into UCS-2 BE"
        );
      }
      newtext.push(bch);
      newtext.push(ch - (bch << 8));
    }
    return String.fromCharCode.apply(undefined, newtext);
  };

  var pdfEscape = (API.__private__.pdfEscape = API.pdfEscape = function(
    text,
    flags
  ) {
    /**

View on GitHub (pinned to a3930ce03a)

Solutions

  1. Confirm `text` is a genuine JavaScript string before calling the text/encoding API (e.g. String(value)).
  2. If you maintain a fork, replace charCodeAt with codePointAt-aware logic or remove the dead guard once you are sure inputs are strings.
  3. Report upstream only if you can reproduce with a plain string literal — include the exact character and code unit value.

Example fix

// before
pdf.text(someValue, x, y); // someValue may not be a string
// after
pdf.text(String(someValue), x, y);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof text !== 'string') text = String(text);
// Optionally strip/replace characters; charCodeAt is always <=0xFFFF so the guard is effectively unreachable.
pdf.text(text, x, y);

Type guard

function isSafeString(v) { return typeof v === 'string'; }

Prevention

When it happens

Trigger: Reached only if `text.charCodeAt(i)` somehow yields a value > 0xFFFF before `bch >> 8` is evaluated. With a standard ECMAScript string this cannot happen; it would require a non-string `text` or a tampered/host engine. The isUnicode flag must be true (font flagged as Unicode) to enter this branch.

Common situations: Essentially never observed in real usage because charCodeAt is bounded at 16 bits. If reported, it usually indicates the stack trace is stale, the text argument was not a real string, or a fork modified the encoding path.

Related errors


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