Repository navigation
Conversation
A route change can remove the <dialog> before a show() queued by
nextTick runs. showModal() then throws InvalidStateError ("Element is
not connected"). show() now returns early for a disconnected dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Generated-By: PostHog Desktop
Task-Id: 67290182-7f62-443c-bc85-43c4a95fe52a
ismail9k
left a comment
There was a problem hiding this comment.
Reviewed with Codex (code pass), checked against the code.
Findings: 0 Critical, 0 Important, 0 Minor.
Intent pass: skipped — the PR links no intent issue (no Closes # / Relates to #). Checked against the PR description instead: the guard and test do what it says.
Merge note — this branch conflicts with main. Since this branch was cut, main landed f259e60 (fix: never show I9kModal's dialog again once it unmounts), which fixes the same InvalidStateError for the route-change / <Suspense> unmount race with an unmounting flag in show() and onNativeClose(). The isConnected guard still adds value on top of it: it covers a dialog that leaves the document while the component stays mounted (a detached subtree, a <KeepAlive>-cached page getting an open update), where unmounting stays false. Resolve the conflict by keeping both checks:
if (unmounting || !element || !element.isConnected || isShown(element)) return;main's showModal stand-in in tests/I9kModal.test.ts already throws on a disconnected element, so this PR's change to that mock is redundant — keep main's and add only the new test.
…l-when-the-e18691 Keep both guards in show(): main's `unmounting` flag for the Suspense unmount race, and this branch's `isConnected` check for a dialog that leaves the document while the modal stays mounted. Keep main's showModal test stand-in, which already throws on a disconnected element. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Answering #39 (review):
Verified on 03830f5: |
Problem
InvalidStateError("Element is not connected") when they moved to the next lesson. The user saw nothing break. The cost is noise in error tracking.show()runs afternextTick, from theopenwatcher and from the re-show inonNativeClose. If a route change removes the<dialog>first, the template ref still points at the old element, andshowModal()throws.Changes
show()returns early when the dialog is not connected to the document.showModal()now throws on a disconnected element, the same as a browser does.InvalidStateError.Risk
<dialog>element is attached again later. No current flow does this, so this PR does not addonActivatedhandling.Verification
npm test(full suite)InvalidStateErrornpm run format:checknpm run lintnpm run typecheckFollow-up
@9klabs/designin the 9k.school learner app after this merges.Agent context
the9klabs/promptdump, but promptdump does not use@9klabs/design. The fix belongs in this repository, so the PR is here./_nuxt/chunk has no source maps.🤖 Generated with Claude Code
Created with PostHog Desktop from this inbox report.