Describe the bug
Unmounting a conditionally rendered Command can emit Svelte's derived_inert warning:
[svelte] derived_inert
Reading a derived belonging to a now-destroyed effect may result in stale values
https://svelte.dev/e/derived_inert
Closing a nested picker unmounts its Command root and can produce the warning during teardown. The command still closes correctly, so the observed impact is warning noise.
The timing and source suggest that deferred Command work outlives its component. One suspected path starts in registerItem(): its disposer can call #selectFirstItem(), whose afterTick callback calls getValidItems() and reads the root's derived ref after destruction.
Deferred sorting, scrolling, and #scheduleUpdate() callbacks are also not teardown-aware in bits-ui@2.19.0.
This appears to be the same lifecycle-error family as issue #2080, fixed by PR #2087 and the deferred-work findings in issue #2103 and issue #2106.
PR #2107 likewise prevents access to a destroyed boxed ref by checking non-reactive lifecycle state first. None of these changes cover Command.
Every deferred CommandRootState callback should return before reading reactive state after teardown. afterTick work needs a lifecycle guard; cancellable work should also be cancelled during teardown.
Reproduction
https://stackblitz.com/edit/vitejs-vite-ykwxohtm?file=src%2FApp.svelte
Logs
[svelte] derived_inert
Reading a derived belonging to a now-destroyed effect may result in stale values
https://svelte.dev/e/derived_inert
System Info
bits-ui: 2.19.0
svelte: 5.56.5
@sveltejs/kit: 2.69.3
bun: 1.3.14
Severity
annoyance
Describe the bug
Unmounting a conditionally rendered
Commandcan emit Svelte'sderived_inertwarning:Closing a nested picker unmounts its
Commandroot and can produce the warning during teardown. The command still closes correctly, so the observed impact is warning noise.The timing and source suggest that deferred
Commandwork outlives its component. One suspected path starts inregisterItem(): its disposer can call#selectFirstItem(), whoseafterTickcallback callsgetValidItems()and reads the root's derivedrefafter destruction.Deferred sorting, scrolling, and
#scheduleUpdate()callbacks are also not teardown-aware inbits-ui@2.19.0.This appears to be the same lifecycle-error family as issue #2080, fixed by PR #2087 and the deferred-work findings in issue #2103 and issue #2106.
PR #2107 likewise prevents access to a destroyed boxed ref by checking non-reactive lifecycle state first. None of these changes cover
Command.Every deferred
CommandRootStatecallback should return before reading reactive state after teardown.afterTickwork needs a lifecycle guard; cancellable work should also be cancelled during teardown.Reproduction
https://stackblitz.com/edit/vitejs-vite-ykwxohtm?file=src%2FApp.svelte
Logs
[svelte] derived_inert Reading a derived belonging to a now-destroyed effect may result in stale values https://svelte.dev/e/derived_inertSystem Info
Severity
annoyance