Repository navigation
adapter-cloudflare: the runtime types from wrangler types merge with lib.dom's Element, so HTMLSelectElement is no longer assignable to HTMLElement #17372
Description
Activity
svelte-triage-bot commented
on Oct 7, 2026 ContributorMore actionsI reproduced the issue, but could not produce a safe, verified fix.
What I tried
- Loaded adapter-cloudflare: the runtime types from
wrangler typesmerge with lib.dom'sElement, soHTMLSelectElementis no longer assignable toHTMLElement#17372 and its comments through the GitHub connection: The issue is open with no comments or closing PR. It confirms that Wrangler's global HTMLRewriter Element merges with lib.dom and changes HTMLSelectElement assignability. - Ran the standalone reproduction with typescript@6.0.3 and wrangler@4.147.0:
npx tsc --noEmit --strict --lib es2022,dom --skipLibCheck repro.ts worker-configuration.d.tsfailed with TS2322: HTMLSelectElement.remove(): void is incompatible with Element.remove(): Element. Omitting the generated declarations passed. - Ran the reported
npx sv@1.1.0 createCloudflare Workers setup, generated types, added Select.svelte, and rannpm run check: The generated project failed exactly at<select bind:this={ref}>with the reported HTMLSelectElement-to-HTMLElement diagnostic. - Linked the generated reproduction to current local Kit and adapter-cloudflare packages and reran
npm run check: Current source still failed with the identical diagnostic, confirming this is not already fixed in the checkout. - Reduced the failure in packages/adapter-cloudflare/test/apps/workers and ran Wrangler type generation, SvelteKit sync, and svelte-check: The in-checkout app failed for the same reason after adding only an HTMLElement state variable and select bind:this. The temporary tracked fixture change was restored afterward.
- Searched prior issues and PRs in sveltejs/kit and sveltejs/cli: No open PR directly addresses adapter-cloudflare: the runtime types from
wrangler typesmerge with lib.dom'sElement, soHTMLSelectElementis no longer assignable toHTMLElement#17372 or the DOM collision. PR feat:@cloudflare/vite-pluginintegration, take 2 #16705 is a broader Cloudflare Vite plugin draft and does not isolate runtime declarations. - Inspected prior type-collision fix fix: don't load ambient worker types #8483 and issue adapter-cloudflare@1.0.0-next.36 ambient.d.ts breaks DOM manipulation function types #8268: Kit previously fixed the same ambient-type failure class by stopping automatic global Worker type loading and using selective imports. Restoring ambient Worker declarations would regress that fix.
- Inspected Cloudflare guidance and 🐛 BUG: TypeScript type incompatibility between standard Request and @cloudflare/workers-types Request cloudflare/workers-sdk#10108: Cloudflare explicitly treats Worker runtime declarations and lib.dom as independent, incompatible environments.
skipLibCheckcannot stop declaration merging from changing user-code assignability. - Tested
wrangler types --include-runtime=falseand selectiveimport('@cloudflare/workers-types').Typedeclarations: Runtime-disabled generation avoids the DOM collision. A generated app excluding the full runtime file and selectively typingcloudflare:workersplus Request.cf passed svelte-check, including both the select binding and a typed env.ASSETS.fetch call. - Audited Wrangler's runtime-disabled Env output and binding generation: Env-only output still references many unqualified, evolving Worker types including Fetcher, KVNamespace, DurableObjectNamespace, R2Bucket, D1Database, Queue, Workflow, AI, and experimental bindings. Shipping a static alias list in Kit would be brittle and would no longer match compatibility dates and flags.
- Reviewed history for PRs docs: mention
wrangler typesin cloudflare adapter #16808, fix cloudflare docs types #16810, breaking: Move cloudflare bindings fromplatformtocloudflare:workers#16754, and fix: avoid colliding with user-typedplatform.env#16043 and recorded /workspace/notes.md: The current Wrangler strategy intentionally replaced incomplete manual types to preserve generated binding/runtime accuracy; Kit 3 also moved APIs from App.Platform to cloudflare:workers. The failing sv template configuration lives in the separate sveltejs/cli repository. - Checked the Kit working tree after investigation: The branch is clean with no product changes, commit, or push. Only ignored generated test artifacts remain.
Why I stopped
The bug is reproducible, but a safe fix is not practical within this Kit checkout. The root cause is combining two ambient libraries that Cloudflare intentionally does not support together. Symptom patches such as augmenting Element.remove or relying on skipLibCheck leave many other Request, Headers, Response, stream, cache, WebSocket, and HTMLRewriter collisions.--include-runtime=falseis safe for DOM types, but its generated Env references a large and changing set of Worker globals; preserving useful, compatibility-date-aware typing requires Cloudflare to provide an isolated/importable generated type surface, or requires a coordinated redesign of adapter typing and the sveltejs/cli template (which owns the reported generated tsconfig/App.Platform setup). Reverting Kit docs to hand-maintained selective bindings would be incomplete, while shipping a static alias list would drift from Wrangler configurations. No unverified patch was committed or pushed.- Loaded adapter-cloudflare: the runtime types from
Describe the bug
The adapter docs say to run
wrangler typesso thatplatformcan be typed, and thesvtemplate puts the generatedworker-configuration.d.tsincompilerOptions.types. That file declares the HTMLRewriter API as global interfaces, among them:$app/tsconfigsetslib: ["esnext", "DOM", "DOM.Iterable"], so this declaration merges with lib.dom'sElement. lib.dom'sHTMLSelectElementoverridesremoveasremove(index?: number): void; after the merge,Element.removealso has the(): Elementsignature, and the override no longer satisfies it:In practice: any
bind:thisfrom a<select>into anHTMLElement | nullfailssvelte-check. shadcn-svelte'snative-selectdoes exactly that, sosv createwith the Cloudflare adapter plusshadcn-svelte add native-selectdoes not passpnpm check.Cloudflare treats the overlap as intended. In cloudflare/workers-sdk#10108 a maintainer wrote that "Cloudflare Workers types are intentionally designed to be used independently from DOM types, not alongside them" and closed the issue. The setup the adapter docs and the
svtemplate produce is that combination, which is why I am filing this here rather than there.Reproduction
No SvelteKit needed; the clash is between lib.dom and the generated file:
The same
tsccall withoutworker-configuration.d.tspasses.In a SvelteKit project:
Logs
Same result with TypeScript 5.9 and 6.0.3.
System Info
Severity
serious, but I can work around it
Additional Information
wrangler types --include-runtime=falseemits only theEnvinterface, which has no DOM overlap, but thenFetcher,ExecutionContextandIncomingRequestCfPropertiesare undefined andApp.Platformcannot be typed the way the docs show. If the adapter shipped those few types itself, projects could generateEnvonly and keep lib.dom intact. Failing that, a note in the adapter docs that the runtime types andbind:thison form elements do not mix would save the next person the afternoon.