solidjs/solid · warning
computations created outside a `createRoot` or `render` will
Error message
computations created outside a `createRoot` or `render` will never be disposed
What it means
When a computation (createEffect/createMemo/createComputed etc.) is created with Owner === null, it is attached to the global UNOWNED graph and will never be disposed automatically, leaking memory and updates. Solid logs this dev-only warning; in production the computation still runs, just unowned.
Source
Thrown at packages/solid/src/reactive/signal.ts:1469
updatedAt: null,
owned: null,
sources: null,
sourceSlots: null,
cleanups: null,
value: init,
owner: Owner,
context: Owner ? Owner.context : null,
pure
};
if (Transition && Transition.running) {
c.state = 0;
c.tState = state;
}
if (Owner === null)
IS_DEV &&
console.warn(
"computations created outside a `createRoot` or `render` will never be disposed"
);
else if (Owner !== UNOWNED) {
if (Transition && Transition.running && (Owner as Memo<Init, Next>).pure) {
if (!(Owner as Memo<Init, Next>).tOwned) (Owner as Memo<Init, Next>).tOwned = [c];
else (Owner as Memo<Init, Next>).tOwned!.push(c);
} else {
if (!Owner.owned) Owner.owned = [c];
else Owner.owned.push(c);
}
}
if (IS_DEV && options && options.name) c.name = options.name;
if (ExternalSourceConfig && c.fn) {
const sourceFn = c.fn;
const [track, trigger] = createSignal<void>(undefined, { equals: false });
const ordinary = ExternalSourceConfig.factory(sourceFn, trigger);View on GitHub (pinned to f47845f9cc)
Solutions
- Wrap the reactive setup in createRoot(dispose => ...) so computations get an owner
- Move the effect inside a component rendered by render(), which creates its own root
- For intentionally global effects, accept the warning in dev or use a dedicated root island you dispose on shutdown
Example fix
// before
createEffect(() => document.title = title()); // module scope: never disposed
// after
createRoot((dispose) => {
createEffect(() => (document.title = title()));
// call dispose() when the app tears down
}); Defensive patterns
Strategy: validation
Validate before calling
import { getOwner, createRoot } from 'solid-js';
export function withRoot<T>(fn: () => T): T {
return getOwner() ? fn() : createRoot((dispose) => { const r = fn(); queueMicrotask(dispose); return r; });
} Type guard
import { getOwner } from 'solid-js';
const hasOwner = (): boolean => getOwner() !== null; Prevention
- Create effects only inside a root (render or createRoot)
- Dispose standalone roots when their island unmounts
- Audit module-scope reactive calls during code review
When it happens
Trigger: Calling createEffect/createComputed/createMemo at module scope or outside render()/createRoot; standalone reactive setups in scripts, workers, or top-level await contexts.
Common situations: Bootstrapping reactive logic at app entry before render; extracting effects into non-component utilities; SSR code paths creating effects outside roots.
Related errors
- cleanups created outside a `createRoot` or `render` will nev
- error handlers created outside a `createRoot` or `render` wi
- Dispose method must be an explicit argument to createRoot fu
- You appear to have multiple instances of Solid. This can lea
- Cannot mutate a Store directly
AI-assisted analysis of solidjs/solid@f47845f9cc (2026-08-27).
Data as JSON: /api/errors/edb663e72b3b47e0.
Report an issue: GitHub.