Skip to content

fix(engines): guard usePdfiumEngine success path against cancellation (Strict Mode)#700

Open
junwen-k wants to merge 1 commit into
embedpdf:mainfrom
junwen-k:fix/pdfium-engine-strict-mode-guard
Open

fix(engines): guard usePdfiumEngine success path against cancellation (Strict Mode)#700
junwen-k wants to merge 1 commit into
embedpdf:mainfrom
junwen-k:fix/pdfium-engine-strict-mode-guard

Conversation

@junwen-k

@junwen-k junwen-k commented Jul 26, 2026

Copy link
Copy Markdown

Problem

usePdfiumEngine's init effect only checks its cancelled flag on the error path — the success path always calls setEngine. Under React Strict Mode (Next.js dev default), the effect mounts → cleans up → remounts before the first createPdfiumEngine resolves. Cleanup ran while engineRef.current was still null, so it disposed nothing; then both invocations resolve and call setEngine with two different engine identities.

Result: any consumer keyed on the engine (e.g. <EmbedPDF>, keyed on [engine, plugins]) remounts, abandoning an in-flight document load, and the first engine leaks.

Fix

Check cancelled after the engine is created; if the effect was already torn down, dispose the freshly created engine and return before committing it. Engine disposal is factored into a small disposeEngine(engine) helper, which also captures the engine locally in the teardown path — so a wasmUrl change mid-init can no longer destroy the replacement engine from inside the old close callback.

ignore is already imported and used, so no new imports. This is the shared React/Preact hook; the Svelte/Vue variants don't share it and are untouched. Includes a patch changeset for @embedpdf/engines.

@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

@junwen-k is attempting to deploy a commit to the OpenBook Team on Vercel.

A member of the Team first needs to authorize it.

The init effect only checked its `cancelled` flag on the error path, so
under React Strict Mode's dev mount/unmount/remount it created two engines
and called `setEngine` for both. The second engine identity remounts any
consumer keyed on the engine (e.g. `<EmbedPDF>`), abandoning an in-flight
document load, and the first engine leaks because the cleanup that ran saw
`engineRef.current === null`.

Discard the freshly created engine if the effect was already torn down, and
factor engine disposal into a `disposeEngine` helper so teardown captures its
target locally — a `wasmUrl` change mid-init can no longer destroy the
replacement engine from within the old close callback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@junwen-k
junwen-k force-pushed the fix/pdfium-engine-strict-mode-guard branch from 47823a2 to 7cfe464 Compare July 26, 2026 09:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant