{"record":{"id":"4e46081a0e0cb00f","repo":"gatsbyjs/gatsby","slug":"unhandled-exception","errorCode":null,"errorMessage":"UNHANDLED EXCEPTION","messagePattern":"UNHANDLED EXCEPTION","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/gatsby-cli/src/index.ts","lineNumber":73,"sourceCode":"//     `)\n//   )\n// }\n\nprocess.on(`unhandledRejection`, reason => {\n  // This will exit the process in newer Node anyway so lets be consistent\n  // across versions and crash\n\n  // reason can be anything, it can be a message, an object, ANYTHING!\n  // we convert it to an error object so we don't crash on structured error validation\n  if (!(reason instanceof Error)) {\n    reason = new Error(util.format(reason))\n  }\n\n  report.panic(`UNHANDLED REJECTION`, reason as Error)\n})\n\nprocess.on(`uncaughtException`, error => {\n  report.panic(`UNHANDLED EXCEPTION`, error)\n})\n\ncreateCli(process.argv)\n","sourceCodeStart":55,"sourceCodeEnd":77,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-cli/src/index.ts#L55-L77","documentation":"Top-level `process.on('uncaughtException', ...)` handler installed by the gatsby CLI. Any exception thrown in a synchronous scope (or an async scope without a catch) that reaches the event loop uncaught triggers this; the handler calls `report.panic` with the error and the process exits. The literal message is just a label; the attached error carries the real cause.","triggerScenarios":"Synchronous throw outside any try/catch (e.g. accessing a property of undefined in `gatsby-config`), or an error thrown in a callback/timer that nothing catches. The handler guarantees a structured panic and clean exit instead of a raw Node crash.","commonSituations":"Typo or null-deref in `gatsby-config.js`/`gatsby-node.js`; a plugin throwing synchronously in a lifecycle hook; a worker/timer callback raising an error; an incompatible plugin version throwing at load time.","solutions":["Inspect the attached error stack in the panic output to find the throwing file and line.","Add a try/catch around the throwing code or fix the null/undefined access.","Reproduce with `node --inspect` or `gatsby <cmd> --verbose` for a fuller stack.","Update/remove the plugin or user code identified as the source."],"exampleFix":"// before: gatsby-config.js throws on missing env\nmodule.exports = {\n  siteMetadata: { key: process.env.API_KEY.toLowerCase() }  // API_KEY undefined\n}\n\n// after\nconst apiKey = process.env.API_KEY\nif (!apiKey) throw new Error('API_KEY env var is required')\nmodule.exports = { siteMetadata: { key: apiKey.toLowerCase() } }","handlingStrategy":"try-catch","validationCode":"// Wrap risky config/node code in try/catch to convert throws to structured errors\ntry { module.exports = require('./gatsby-config.safe') } catch (e) { console.error(e); process.exit(1) }","typeGuard":null,"tryCatchPattern":"process.on('uncaughtException', (error) => {\n  reporter.panic('UNHANDLED EXCEPTION', error)\n})","preventionTips":["Validate env/inputs in `gatsby-config`/`gatsby-node` before use.","Reproduce with `--verbose`/`--inspect` to surface the originating throw.","Update plugins that throw synchronously in lifecycle hooks."],"tags":["cli","uncaught-exception","process","lifecycle"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}