mozilla/pdf.js · error · Error

The overlay is already registered.

Error message

The overlay is already registered.

What it means

Thrown by OverlayManager.register when the given dialog element is already present in the internal WeakMap (#overlays.has(dialog) is true). Each overlay must be registered exactly once to attach its cancel-listener and state.

Source

Thrown at web/overlay_manager.js:36

  #active = null;

  get active() {
    return this.#active;
  }

  /**
   * @param {HTMLDialogElement} dialog - The overlay's DOM element.
   * @param {boolean} [canForceClose] - Indicates if opening the overlay closes
   *                  an active overlay. The default is `false`.
   * @returns {Promise} A promise that is resolved when the overlay has been
   *                    registered.
   */
  async register(dialog, canForceClose = false) {
    if (typeof dialog !== "object") {
      throw new Error("Not enough parameters.");
    } else if (this.#overlays.has(dialog)) {
      throw new Error("The overlay is already registered.");
    }
    this.#overlays.set(dialog, { canForceClose });

    dialog.addEventListener("cancel", ({ target }) => {
      if (this.#active === target) {
        this.#active = null;
      }
    });
  }

  /**
   * @param {HTMLDialogElement} dialog - The overlay's DOM element.
   * @returns {Promise} A promise that is resolved when the overlay has been
   *                    opened.
   */
  async open(dialog) {
    if (!this.#overlays.has(dialog)) {
      throw new Error("The overlay does not exist.");

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Register each dialog only once during initial setup.
  2. Guard with the internal state: check OverlayManager.active or track registration in your own flag before calling register.
  3. Remove duplicate register calls introduced by refactoring or shared utilities.

Example fix

// before
await OverlayManager.register(dialog); // called again later -> throws

// after
if (!overlayRegistered.has(dialog)) {
  await OverlayManager.register(dialog);
  overlayRegistered.add(dialog);
}
Defensive patterns

Strategy: validation

Validate before calling

const registered = new WeakSet();
if (!registered.has(dialog)) {
  await OverlayManager.register(dialog);
  registered.add(dialog);
}

Try / catch

try {
  await OverlayManager.register(dialog);
} catch (e) {
  if (e.message === 'The overlay is already registered.') return; // idempotent
  throw e;
}

Prevention

When it happens

Trigger: Calling register(dialog) twice with the same HTMLDialogElement reference. Common in apps that re-init UI or call setup routines repeatedly without teardown.

Common situations: Re-running viewer initialization, double-binding on a reused dialog element, or calling register from multiple components that share the dialog.

Related errors


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