mozilla/pdf.js · error · Error

Transport destroyed

Error message

Transport destroyed

What it means

A generic Error in WorkerTransport.getPage: after the sendWithPromise('GetPage') resolves with pageInfo, the transport checks this.destroyed before constructing the PDFPageProxy. If the document was destroyed while the GetPage round-trip was in flight, the page cannot be created and the promise rejects with 'Transport destroyed'.

Source

Thrown at src/display/api.js:3037

      pageNumber <= 0 ||
      pageNumber > this.pagesMapper.pagesNumber
    ) {
      return Promise.reject(new Error("Invalid page request."));
    }
    const pageIndex = pageNumber - 1;
    const newPageIndex = this.pagesMapper.getPageId(pageNumber) - 1;

    const cachedPromise = this.#pagePromises.get(pageIndex);
    if (cachedPromise) {
      return cachedPromise;
    }
    const promise = this.messageHandler
      .sendWithPromise("GetPage", {
        pageIndex: newPageIndex,
      })
      .then(pageInfo => {
        if (this.destroyed) {
          throw new Error("Transport destroyed");
        }
        if (pageInfo.refStr) {
          this.#pageRefCache.set(pageInfo.refStr, newPageIndex);
        }

        const page = new PDFPageProxy(
          pageIndex,
          pageInfo,
          this,
          this.pagesMapper,
          this._params.pdfBug
        );
        this.#pageCache.set(pageIndex, page);
        return page;
      });
    this.#pagePromises.set(pageIndex, promise);
    return promise;
  }

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Await destroy() before issuing or relying on getPage results, or stop requesting pages once destroy begins.
  2. Treat 'Transport destroyed' as an expected rejection when the user navigates away.
  3. Guard prefetch loops with an 'isAlive' flag set false on destroy.

Example fix

let alive = true;
loadingTask.promise.then(d => {
  for (let i = 1; i <= d.numPages && alive; i++) {
    d.getPage(i).catch(e => {
      if (/Transport destroyed/.test(e.message)) return;
      throw e;
    });
  }
});
// on teardown:
alive = false;
await loadingTask.destroy();
Defensive patterns

Strategy: try-catch

Validate before calling

// Guard prefetch loops with an alive flag.
let alive = true;
async function prefetch(doc) {
  for (let i = 1; i <= doc.numPages && alive; i++) {
    await doc.getPage(i).catch(e => {
      if (/Transport destroyed/.test(e.message)) return;
      throw e;
    });
  }
}
// teardown:
alive = false;
await loadingTask.destroy();

Try / catch

try {
  const page = await doc.getPage(n);
} catch (e) {
  if (/Transport destroyed/.test(e.message)) return null; // closed mid-request
  throw e;
}

Prevention

When it happens

Trigger: Calling doc.getPage(n) and then calling loadingTask.destroy() (or triggering transport destruction) before the page info returns; navigating away mid-page-load; cancelling a multi-page prefetch loop.

Common situations: SPA route changes during page prefetch; thumbnail generation interrupted by close; rapid document switches in a viewer.

Related errors


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