solidjs/solid · warning
error handlers created outside a `createRoot` or `render` wi
Error message
error handlers created outside a `createRoot` or `render` will never be run
What it means
onError registers an error handler on the current reactive Owner. With Owner === null (no createRoot/render in scope), there is nothing to attach to, so the handler would never run; Solid warns in dev instead of failing silently. It is a console warning, not a thrown error.
Source
Thrown at packages/solid/src/reactive/signal.ts:1827
};
}
type TODO = any;
/**
* @deprecated since version 1.7.0 and will be removed in next major - use catchError instead
* onError - run an effect whenever an error is thrown within the context of the child scopes
* @param fn an error handler that receives the error
*
* * If the error is thrown again inside the error handler, it will trigger the next available parent handler
*
* @description https://docs.solidjs.com/reference/reactive-utilities/catch-error
*/
export function onError(fn: (err: Error) => void): void {
ERROR || (ERROR = Symbol("error"));
if (Owner === null)
IS_DEV &&
console.warn("error handlers created outside a `createRoot` or `render` will never be run");
else if (Owner.context === null || !Owner.context[ERROR]) {
// terrible de-opt
Owner.context = { ...Owner.context, [ERROR]: [fn] };
mutateContext(Owner, ERROR, [fn]);
} else Owner.context[ERROR].push(fn);
}
function mutateContext(o: Owner, key: symbol, value: any) {
if (o.owned) {
for (let i = 0; i < o.owned.length; i++) {
if (o.owned[i].context === o.context) mutateContext(o.owned[i], key, value);
if (!o.owned[i].context) {
o.owned[i].context = o.context;
mutateContext(o.owned[i], key, value);
} else if (!o.owned[i].context[key]) {
o.owned[i].context[key] = value;
mutateContext(o.owned[i], key, value);
}View on GitHub (pinned to f47845f9cc)
Solutions
- Move onError inside a component or createRoot so it has an owner
- For top-level error handling, wrap the app in createRoot and register onError there
- Use ErrorBoundary around subtrees for rendering errors instead of rootless onError
Example fix
// before
onError((err) => log(err)); // module scope: never runs
// after
createRoot((dispose) => {
onError((err) => log(err));
render(() => <App />, root);
}); Defensive patterns
Strategy: validation
Validate before calling
import { getOwner } from 'solid-js';
if (getOwner()) onError(fn); else globalErrorHandler = fn; Type guard
import { getOwner } from 'solid-js';
const hasOwner = (): boolean => getOwner() !== null; Prevention
- Register onError inside components or a createRoot
- Use ErrorBoundary for render errors
- Check getOwner() before registering lifecycle handlers in shared utilities
When it happens
Trigger: Calling onError(fn) at module scope, in plain event handlers outside the tree, or in scripts run before render(); any onError call where createRoot was never entered.
Common situations: Adding global error handling at app entry before render(); extracting error logic into utils called outside components; testing components without a root.
Related errors
- Dispose method must be an explicit argument to createRoot fu
- cleanups created outside a `createRoot` or `render` will nev
- computations created outside a `createRoot` or `render` will
- 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/bef16d9c1f068d8a.
Report an issue: GitHub.