{"record":{"id":"59aea3828c1143ff","repo":"gatsbyjs/gatsby","slug":"unhandled-rejection","errorCode":null,"errorMessage":"UNHANDLED REJECTION","messagePattern":"UNHANDLED REJECTION","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/gatsby-cli/src/index.ts","lineNumber":69,"sourceCode":"//     report.stripIndent(`\n//       Node.js ${version} has reached End of Life status on 31 December, 2019.\n//       Gatsby will only actively support ${NEXT_MIN_NODE_VERSION} or higher and drop support for Node 8 soon.\n//       Please upgrade Node.js to a currently active LTS release: https://gatsby.dev/upgrading-node-js\n//     `)\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":51,"sourceCodeEnd":77,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-cli/src/index.ts#L51-L77","documentation":"Top-level `process.on('unhandledRejection', ...)` handler installed by the gatsby CLI. Any Promise rejection that nothing else `.catch`es reaches here; the handler wraps non-Error reasons into Errors and calls `report.panic`, which logs structured output and exits nonzero. The message is a generic label; the real cause is the wrapped `reason`.","triggerScenarios":"An async operation anywhere in the gatsby process rejects and no `.catch()`/`try-await` handles it. Examples: an unawaited `graphql()` call in `gatsby-node`, a plugin's async hook that throws, a fetch/filesystem rejection during build.","commonSituations":"Plugin or theme bug surfacing an unhandled rejection; `gatsby-node`/`gatsby-config` async code missing await or try/catch; Node version differences where unhandled rejections abort by default; network errors in user code called from lifecycle hooks.","solutions":["Read the wrapped `reason`/stack in the panic output to locate the rejecting code.","Add `.catch()` or wrap the `await` in try/catch at the call site identified by the stack.","Ensure all async lifecycle exports (`createPages`, etc.) fully await their promises.","Update plugins/themes whose unhandled rejections are the source."],"exampleFix":"// before: unawaited rejection\nexports.createPages = ({ graphql }) => {\n  graphql(`{ ... }`).then(d => buildPages(d))  // rejection unhandled\n}\n\n// after\nexports.createPages = async ({ graphql, reporter }) => {\n  try {\n    const { data } = await graphql(`{ ... }`)\n    buildPages(data)\n  } catch (e) { reporter.error('createPages failed', e) }\n}","handlingStrategy":"try-catch","validationCode":"// Ensure all async lifecycle exports await and catch\nasync function safeRun(fn) { try { await fn() } catch (e) { reporter.error(e) } }","typeGuard":null,"tryCatchPattern":"process.on('unhandledRejection', (reason) => {\n  const err = reason instanceof Error ? reason : new Error(String(reason))\n  reporter.panic('UNHANDLED REJECTION', err)\n})","preventionTips":["Always `await` promises in `gatsby-node`/`gatsby-config` lifecycle hooks.","Add `.catch()` to fire-and-forget promises.","Keep plugins updated so their internal rejections are handled."],"tags":["cli","unhandled-rejection","process","lifecycle","async"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}