mozilla/pdf.js · error · Error

Invalid optionalContentConfigPromise: ${promise}

Error message

Invalid optionalContentConfigPromise: ${promise}

What it means

Thrown by PDFViewer.optionalContentConfigPromise setter when the value is not a Promise instance (instanceof Promise check fails). Optional content (OCG/OCMD layers) are refreshed asynchronously and require a promise resolving to an OptionalContentConfig.

Source

Thrown at web/pdf_viewer.js:2265

    if (!this.pdfDocument) {
      return Promise.resolve(null);
    }
    if (!this._optionalContentConfigPromise) {
      console.error("optionalContentConfigPromise: Not initialized yet.");
      // Prevent issues if the getter is accessed *before* the `onePageRendered`
      // promise has resolved; won't (normally) happen in the default viewer.
      return this.pdfDocument.getOptionalContentConfig({ intent: "display" });
    }
    return this._optionalContentConfigPromise;
  }

  /**
   * @param {Promise<OptionalContentConfig>} promise - A promise that is
   *   resolved with an {@link OptionalContentConfig} instance.
   */
  set optionalContentConfigPromise(promise) {
    if (!(promise instanceof Promise)) {
      throw new Error(`Invalid optionalContentConfigPromise: ${promise}`);
    }
    if (!this.pdfDocument) {
      return;
    }
    if (!this._optionalContentConfigPromise) {
      // Ignore the setter *before* the `onePageRendered` promise has resolved,
      // since it'll be overwritten anyway; won't happen in the default viewer.
      return;
    }
    this._optionalContentConfigPromise = promise;

    this.refresh(false, { optionalContentConfigPromise: promise });

    this.eventBus.dispatch("optionalcontentconfigchanged", {
      source: this,
      promise,
    });
  }

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Pass a Promise: viewer.optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({ intent: 'display' }).
  2. Wrap a resolved config: viewer.optionalContentConfigPromise = Promise.resolve(config).
  3. Ensure the value is a real Promise (await/import correctness) before assigning.

Example fix

// before
viewer.optionalContentConfigPromise = pdfDocument.getOptionalContentConfig({ intent: 'display' });
// (getOptionalContentConfig returns the config synchronously, not a Promise)

// after
viewer.optionalContentConfigPromise = Promise.resolve(
  pdfDocument.getOptionalContentConfig({ intent: 'display' })
);
Defensive patterns

Strategy: type-guard

Validate before calling

const config = pdfDocument.getOptionalContentConfig({ intent: 'display' });
const promise = (config instanceof Promise) ? config : Promise.resolve(config);
viewer.optionalContentConfigPromise = promise;

Type guard

function isPromise(v) {
  return v instanceof Promise;
}

Prevention

When it happens

Trigger: Setting viewer.optionalContentConfigPromise = configObject, a plain value, null, or a thenable that is not a native Promise. Also when assigning before the document is loaded (handled by no-op, but type still checked).

Common situations: Passing the config directly instead of a promise; using a non-native thenable (some polyfills); forgetting to wrap: Promise.resolve(config).

Related errors


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