Skip to content

fix: don't throw from remote form validate() if the form unmounts - #16720

Open
kdelay wants to merge 2 commits into
sveltejs:version-3from
kdelay:fix/issue-16696-validate-after-unmount
Open

fix: don't throw from remote form validate() if the form unmounts#16720
kdelay wants to merge 2 commits into
sveltejs:version-3from
kdelay:fix/issue-16696-validate-after-unmount

Conversation

@kdelay

@kdelay kdelay commented Aug 11, 2026

Copy link
Copy Markdown

closes #16696

validate() checks element before await tick(), but the attachment cleanup sets element = null when the <form> unmounts. If the form is removed while validate() is waiting for that tick — e.g. an {#if} flips right after a fast submission — the resumed call throws:

TypeError: Cannot read properties of null (reading 'querySelector')

The fix re-checks element after the tick and bails out if the form is gone, which matches what the pre-tick check already intends.

Tests

Added a case to the async test app's existing /remote/form/validate route: a form inside an {#if} block, and a button that starts validate() and unmounts the form in the same handler, catching whatever the promise rejects with. The new test fails on version-3 (TypeError: Cannot read properties of null (reading 'querySelector')) and passes with this change.

Rebased onto version-3 at a115a7b and re-verified locally on Node 24.18.0:

  • pnpm lint: 0 errors (one pre-existing warning in src/runtime/server/page/index.js, untouched here).
  • pnpm test:unit: 895 passed, 11 failed. The 11 failures are in kit-prerendering-paths-base and kit-prerendering-options and reproduce identically on unpatched version-3, so they are not from this change.
  • async test app, pnpm test:dev: 193 passed, 103 skipped, 0 failed. The new test also passes in chromium-build and chromium-build-no-js.
  • pnpm check fails on unpatched version-3 as well, with 24 TS2300: Duplicate identifier errors from src/types/ambient.d.ts. This branch changes no types, so I could not get a clean baseline for that step.

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

The element null check in validate() ran before 'await tick()', but the
attachment cleanup sets element to null on unmount. If the <form> was
removed while validate() was waiting for the tick, the resumed call threw
'Cannot read properties of null (reading querySelector)'.

Re-check element after the tick and bail out if the form is gone.
@pkg-svelte-dev

pkg-svelte-dev Bot commented Aug 11, 2026

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from ad40934:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/ad409342628607eb1466a1c2213e3d099ba447e0

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/kit/pr/16720

Note

This PR is from a fork. A maintainer must approve approve each commit before it can be built and installed.

@changeset-bot

changeset-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ad40934

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@kdelay

kdelay commented Aug 11, 2026

Copy link
Copy Markdown
Author

A note on the red lint-all here: it reproduces on the base commit, so it does not come from this PR.

This branch is based on a115a7beb, which is the current version-3 head. The upstream push run for that same commit fails lint-all as well: https://github.com/sveltejs/kit/actions/runs/31442413468/job/93629686461 (failed 2026-08-10 23:32 UTC). I compared the tsc diagnostics from that run with the ones from this PR's run (https://github.com/sveltejs/kit/actions/runs/31455435935/job/93668121269): both report the same 87 errors with an identical file/line/error-code set, mostly TS2339: Property '_' does not exist on type 'SSRManifest' and the TS2300/TS2451 duplicate identifiers between src/types/ambient.d.ts and types/index.d.ts. The last green version-3 run was 0b3e2b386.

The diff here is limited to packages/kit/src/runtime/client/remote-functions/form.svelte.js and the async test app, and it does not touch any type declarations. Every other job on this run is green, including the svelte-async dev and build suites that cover the new test. I am happy to rebase once version-3 is green again.

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.

Remote form validate() crashes with null element if the form unmounts during the internal await tick()

2 participants