{"record":{"id":"bef16d9c1f068d8a","repo":"solidjs/solid","slug":"error-handlers-created-outside-a-createroot-or","errorCode":null,"errorMessage":"error handlers created outside a `createRoot` or `render` will never be run","messagePattern":"error handlers created outside a `createRoot` or `render` will never be run","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/solid/src/reactive/signal.ts","lineNumber":1827,"sourceCode":"  };\n}\n\ntype TODO = any;\n\n/**\n * @deprecated since version 1.7.0 and will be removed in next major - use catchError instead\n * onError - run an effect whenever an error is thrown within the context of the child scopes\n * @param fn an error handler that receives the error\n *\n * * If the error is thrown again inside the error handler, it will trigger the next available parent handler\n *\n * @description https://docs.solidjs.com/reference/reactive-utilities/catch-error\n */\nexport function onError(fn: (err: Error) => void): void {\n  ERROR || (ERROR = Symbol(\"error\"));\n  if (Owner === null)\n    IS_DEV &&\n      console.warn(\"error handlers created outside a `createRoot` or `render` will never be run\");\n  else if (Owner.context === null || !Owner.context[ERROR]) {\n    // terrible de-opt\n    Owner.context = { ...Owner.context, [ERROR]: [fn] };\n    mutateContext(Owner, ERROR, [fn]);\n  } else Owner.context[ERROR].push(fn);\n}\n\nfunction mutateContext(o: Owner, key: symbol, value: any) {\n  if (o.owned) {\n    for (let i = 0; i < o.owned.length; i++) {\n      if (o.owned[i].context === o.context) mutateContext(o.owned[i], key, value);\n      if (!o.owned[i].context) {\n        o.owned[i].context = o.context;\n        mutateContext(o.owned[i], key, value);\n      } else if (!o.owned[i].context[key]) {\n        o.owned[i].context[key] = value;\n        mutateContext(o.owned[i], key, value);\n      }","sourceCodeStart":1809,"sourceCodeEnd":1845,"githubUrl":"https://github.com/solidjs/solid/blob/f47845f9cc16ecbb316aa6560c7161f45af9a3d8/packages/solid/src/reactive/signal.ts#L1809-L1845","documentation":"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.","triggerScenarios":"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.","commonSituations":"Adding global error handling at app entry before render(); extracting error logic into utils called outside components; testing components without a root.","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"],"exampleFix":"// before\nonError((err) => log(err)); // module scope: never runs\n\n// after\ncreateRoot((dispose) => {\n  onError((err) => log(err));\n  render(() => <App />, root);\n});","handlingStrategy":"validation","validationCode":"import { getOwner } from 'solid-js';\nif (getOwner()) onError(fn); else globalErrorHandler = fn;","typeGuard":"import { getOwner } from 'solid-js';\nconst hasOwner = (): boolean => getOwner() !== null;","tryCatchPattern":null,"preventionTips":["Register onError inside components or a createRoot","Use ErrorBoundary for render errors","Check getOwner() before registering lifecycle handlers in shared utilities"],"tags":["solid","onerror","owner","createroot","dev-warning"],"backgroundTag":"lifecycle-outside-reactive-root","analyzedSha":"f47845f9cc16ecbb316aa6560c7161f45af9a3d8","analyzedAt":"2026-08-27T05:39:24.283Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}