{"record":{"id":"c02ec7b44f3ca3d0","repo":"solidjs/solid","slug":"attempting-to-access-a-stale-value-from-name","errorCode":null,"errorMessage":"Attempting to access a stale value from <${name}> that could possibly be undefined. This may occur because you are reading the accessor returned from the component at a time where it has already been unmounted. We recommend cleaning up any stale timers or async, or reading from the initial condition.","messagePattern":"Attempting to access a stale value from <(.+?)> that could possibly be undefined\\. This may occur because you are reading the accessor returned from the component at a time where it has already been unmounted\\. We recommend cleaning up any stale timers or async, or reading from the initial condition\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/solid/src/render/flow.ts","lineNumber":137,"sourceCode":"          ? {\n              equals: (a, b) => !a === !b,\n              name: \"condition\"\n            }\n          : { equals: (a, b) => !a === !b }\n      );\n  return createMemo(\n    () => {\n      const c = condition();\n      if (c) {\n        const child = props.children;\n        const fn = typeof child === \"function\" && child.length > 0;\n        return fn\n          ? untrack(() =>\n              (child as any)(\n                keyed\n                  ? (c as T)\n                  : () => {\n                      if (!untrack(condition)) throw narrowedError(\"Show\");\n                      return conditionValue();\n                    }\n              )\n            )\n          : child;\n      }\n      return props.fallback;\n    },\n    undefined,\n    IS_DEV ? { name: \"value\" } : undefined\n  ) as unknown as JSX.Element;\n}\n\ntype EvalConditions = readonly [number, Accessor<unknown>, MatchProps<unknown>];\n\n/**\n * Switches between content based on mutually exclusive conditions\n * ```typescript","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/solidjs/solid/blob/f47845f9cc16ecbb316aa6560c7161f45af9a3d8/packages/solid/src/render/flow.ts#L119-L155","documentation":"In non-keyed <Show>, the child receives an accessor rather than a value. If Show's condition flips or the component unmounts while that accessor is read (e.g. inside an async callback or stray timer), Solid throws the narrowedError('Show') to reveal the read-after-unmount. The message recommends cleaning up stale async work or reading only while mounted.","triggerScenarios":"Non-keyed <Show when={x}>{(v) => ...}</Show> where the v accessor is captured and called later in a setTimeout, event handler, or promise callback after the condition changed; reading v outside untrack during re-evaluation.","commonSituations":"Passing the accessor into long-lived callbacks instead of the current value; forgetting onCleanup for async tasks; migration from keyed to non-keyed Show changing the child arg from value to accessor.","solutions":["Capture the value, not the accessor: use {(v) => <Child value={v()}>} rendered immediately","Clean up async work with onCleanup so no reads happen after unmount","Switch to keyed mode <Show when={x} keyed> if the child genuinely needs to hold the value across time"],"exampleFix":"// before\n<Show when={user()}>\n  {(user) => {\n    setTimeout(() => api.track(user()), 5000); // accessor read after flip\n    return <Profile user={user()} />;\n  }}\n</Show>\n\n// after\n<Show when={user()} keyed>\n  {(u) => {\n    setTimeout(() => api.track(u), 5000); // value captured\n    return <Profile user={u} />;\n  }}\n</Show>","handlingStrategy":"validation","validationCode":"// capture the value immediately; never retain the accessor\n<Show when={user()} keyed>\n  {(u) => {\n    onCleanup(() => cancelPending());\n    return <Profile user={u} />;\n  }}\n</Show>","typeGuard":"// TS-only habit: type the child as taking the value, forcing keyed\nfunction child(u: User) { ... }\n<Show when={user()} keyed>{(u) => child(u)}</Show>","tryCatchPattern":"try { const v = accessor(); } catch (e) { if (/stale value/.test(String(e))) return null; /* branch no longer active */ throw e; }","preventionTips":["Use keyed Show when the child must retain the value past render","Read accessors once during render; store the result","Cancel timers/async work in onCleanup to avoid post-unmount reads"],"tags":["solid","show","stale-value","unmount","async"],"backgroundTag":"stale-value-after-unmount","analyzedSha":"f47845f9cc16ecbb316aa6560c7161f45af9a3d8","analyzedAt":"2026-08-27T05:39:24.283Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}