Repository navigation
Description
Description
The desktop app crashes with Error: Stale read from <Show> when running ~4 agents simultaneously. Also observed on startup when a previous session with active agents is restored. Version 1.2.20.
The v1.2.18–v1.2.20 fixes (152df242, 7665b8e3, cf425d11) addressed 4 files, but 17+ non-keyed callback-form <Show> components remain unfixed.
Steps to Reproduce
- Open a session
- Run ~4 agents in parallel (e.g., multiple Sisyphus-Junior tasks)
- App crashes with the error page showing "Stale read from
<Show>"
Stack Trace
Error: Stale read from <Show>.
ke@tauri://localhost/assets/index-BdH7uL2O.js:1:10362
ge@tauri://localhost/assets/index-BdH7uL2O.js:1:10588
po@tauri://localhost/assets/index-BdH7uL2O.js:1:6910
ie@tauri://localhost/assets/index-BdH7uL2O.js:1:6485
je@tauri://localhost/assets/index-BdH7uL2O.js:1:7919
Go@tauri://localhost/assets/index-BdH7uL2O.js:1:8820
wt@tauri://localhost/assets/index-BdH7uL2O.js:1:8193
O@tauri://localhost/assets/index-BdH7uL2O.js:1:8110
@tauri://localhost/assets/index-BX0_ILPZ.js:2306:44485
Root Cause
@solidjs/router v0.15.4 uses startTransition() internally for all navigation, triggering solidjs/solid#2046.
When a <Show> uses the callback accessor form ({(item) => ...item()...} without keyed), SolidJS passes an accessor that checks untrack(condition) before returning the value. During a transition, the condition can become false on the "old" reactive graph while the accessor is still being called — throwing the error.
Running multiple agents causes rapid state updates (messages, tool calls, status changes) which increases the likelihood of hitting this race condition via the router's transition system.
Remaining Unfixed Instances (v1.2.20)
All use <Show when={...}>{(item) => ...item()...}</Show> without keyed:
| File | Line | when condition |
Startup path? |
|---|---|---|---|
session-header.tsx |
359 | centerMount() |
✅ |
session-header.tsx |
379 | hotkey() |
✅ |
session-header.tsx |
388 | rightMount() |
✅ |
session-new-view.tsx |
65 | sync.project |
✅ |
session-context-usage.tsx |
76 | context() |
✅ |
sidebar-project.tsx |
46 | project() |
✅ |
sidebar-workspace.tsx |
79 | label() |
✅ |
message-timeline.tsx |
734 | comment().selection |
|
context-items.tsx |
55, 77 | item.selection, item.comment |
|
model-tooltip.tsx |
80 | inputs() |
|
settings-providers.tsx |
192 | note(item.id) |
|
session-context-tab.tsx |
319 | systemPrompt() |
|
settings-general.tsx |
506 | linux() |
|
server-row.tsx |
92 | props.conn |
|
error.tsx |
312, 327 | store.actionError, platform.version |
|
desktop/index.tsx (ServerGate) |
484 | serverData |
✅ |
Suggested Fix
Same pattern already applied in v1.2.18 for layout.tsx, terminal-panel.tsx, etc. — add keyed and change item() to item:
// ❌ Vulnerable to stale read during transitions
<Show when={centerMount()}>
{(mount) => <Portal mount={mount()}>...</Portal>}
</Show>
// ✅ Fixed — keyed passes value directly, no accessor check
<Show when={centerMount()} keyed>
{(mount) => <Portal mount={mount}>...</Portal>}
</Show>Fix History
| Version | What was fixed |
|---|---|
| v1.2.18 | layout.tsx, message-timeline.tsx, terminal-panel.tsx, session-side-panel.tsx — added keyed |
| v1.2.20 | Removed startTransition from createTimelineStaging |
| Current | 17+ instances still unfixed |
Environment
- App version: 1.2.20
- Platform: macOS (Tauri desktop)
- SolidJS Router: 0.15.4 (uses
startTransitioninternally) - Trigger: Running ~4 agents in parallel
Activity
github-actions commentedon Mar 6, 2026
This issue might be a duplicate of existing issues. Please check:
<Show>" crash triggered by navigating to a newly-spawned subagent (open)<Show>" error, closed after fix increateTimelineStagingYour analysis of remaining unfixed instances is valuable — if the above issues don't fully cover this, consider linking to them for context.
cyberprophet commentedon Mar 7, 2026
Status Update
The
startTransitionremoval incf425d11(PR #16236) mitigated the most common trigger, but the 17+ unfixed<Show>instances listed in this issue remain.More immediately, the
session-header.tsxcomponent has a separate but related crash (#16459, #16467):current()returnsundefinedwhenoptions()is empty, causingcurrent().idto throw. A fix PR is incoming for that specific crash.The broader
keyedfix was reverted (2094e8b2,eeeb21ff) on Mar 5 — likely due to side effects from changingitem()→itemin callback bodies. Any futurekeyedfix attempt needs to ensure allitem()accessor calls inside the callback are updated toitem(direct value) simultaneously.chris-hatton commentedon Apr 21, 2026
+1 Affected - navigating into / out from sub-agents while multiple agents are running seems to be a hot-bed of very easy to reproduce crashes over recent versions; can these kinds of use-cases not have automated E2E test cases?
cpkt9762 commentedon Apr 23, 2026
Update: 3 more unfixed instances + new trigger path (clicking agent task cards)
Hit the same crash on a newer build (
index-DtwFEwRY.js). Built locally withvite build --sourcemapand mapped the minified stack back to source — trigger lands atpackages/app/src/context/sync.tsx:340, inside thebatch()that runsreconcile(message)+setStore("part", ...)afterfetchMessages.Trigger UX path: clicking an agent task card (subagent invocation card rendered in the message stream as
<a href="...">). Navigation firessyncto reload messages for the new session, the batch reconcile clears the old tool part, and the old<Show>'s callback accessor is read whileconditionhas already flipped falsy inside the same batch → throw.3 additional non-keyed callback-form
<Show>not in the OP listwhenpackages/ui/src/components/basic-tool.tsxprops.triggerHref<a href>(agent/subagent task cards, file-result cards) → session reload → batch reconcilepackages/ui/src/components/tool-error-card.tsxbody()packages/ui/src/components/session-retry.tsxinfo()basic-tool.tsxis the highest-impact one — it's the base wrapper for every tool card (including agent-task cards that show subagent progress), so clicking any of them withtriggerHrefset hits this.Patch (same
keyedpattern used by the earlier v1.2.18 fixes)// packages/ui/src/components/basic-tool.tsx <Show when={props.triggerHref} + keyed fallback={...} > {(href) => ( <Collapsible.Trigger as="a" - href={href()} + href={href} ...Verified locally: typecheck clean, crash no longer reproduces when clicking agent task cards. The
sync.tsxbatch reconcile path is just another way to hit the same shape described in the OP (routerstartTransition+ non-keyed callback<Show>→ solidjs/solid#2046).github-actions commentedon Jul 3, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.