{"record":{"id":"8db14f5f8108d515","repo":"facebook/react","slug":"600","errorCode":"600","errorMessage":"A rejected Promise was passed to React without a `reason` property. React threw a generic error from where the Promise was used to assist in identifying the problematic Promise. Make sure that instrumented Promises correctly set the `reason` property when setting `status` to `'rejected'`.","messagePattern":"A rejected Promise was passed to React without a `reason` property\\. React threw a generic error from where the Promise was used to assist in identifying the problematic Promise\\. Make sure that instrumented Promises correctly set the `reason` property when setting `status` to `'rejected'`\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-server/src/ReactFizzThenable.js","lineNumber":88,"sourceCode":"  switch (thenable.status) {\n    case 'fulfilled': {\n      // This could be a bad instrumentation that doesn't set .value.\n      // We're not type-checking since this is a hot path where you can\n      // track down easily when something becomes `undefined` unexpectedly.\n      const fulfilledValue: T = thenable.value;\n      return fulfilledValue;\n    }\n    case 'rejected': {\n      const rejectedError = thenable.reason;\n\n      // Rejected Promises are rarer so we're doing an extra type-check in\n      // case of a bad instrumentation that doesn't set .reason\n      // If we end up throwing `undefined` it becomes hard to track down\n      // where that throw originated because no callstack would exist.\n      // React would still have a Component stack but that could only be used\n      // as an approximation.\n      if (rejectedError === undefined && !('reason' in thenable)) {\n        throw new Error(\n          'A rejected Promise was passed to React without a `reason` property. ' +\n            'React threw a generic error from where the Promise was used to assist in identifying the problematic Promise. ' +\n            \"Make sure that instrumented Promises correctly set the `reason` property when setting `status` to `'rejected'`.\",\n        );\n      }\n\n      throw rejectedError;\n    }\n    default: {\n      if (typeof thenable.status === 'string') {\n        // Only instrument the thenable if the status if not defined. If\n        // it's defined, but an unknown value, assume it's been instrumented by\n        // some custom userspace implementation. We treat it as \"pending\".\n        // Attach a dummy listener, to ensure that any lazy initialization can\n        // happen. Flight lazily parses JSON when the value is actually awaited.\n        thenable.then(noop, noop);\n      } else {\n        const pendingThenable: PendingThenable<T> = thenable as any;","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-server/src/ReactFizzThenable.js#L70-L106","documentation":"React consumes instrumented promises synchronously via .status/.reason instead of attaching .then handlers. In the rejected branch, if reason is undefined and the object lacks a reason key entirely, React throws this generic error (code 600) at the consumption point — rethrowing a bare undefined would lose the callstack and make the offending promise untraceable.","triggerScenarios":"A promise or thenable passed to use() (or thrown to suspend) whose instrumentation set status = 'rejected' without also setting reason; custom suspense helpers, promise patches, or mocks that set status only.","commonSituations":"Hand-rolled promise instrumentation following older React recipes; test doubles that set promise.status; a library patching global Promise to add status but not reason.","solutions":["When setting promise.status = 'rejected', always also set promise.reason = theError","Update custom instrumentation helpers to follow the full status+reason contract","Upgrade libraries that patch Promise instrumentation"],"exampleFix":"// before\nfunction instrument(promise) {\n  promise.status = 'rejected'; // no reason -> generic error later\n  return promise;\n}\n\n// after\nfunction instrument(promise, error) {\n  promise.status = 'rejected';\n  promise.reason = error;\n  return promise;\n}","handlingStrategy":"validation","validationCode":"function assertInstrumented(promise) {\n  if (promise.status === 'rejected' && !('reason' in promise)) {\n    throw new TypeError('Rejected promise is missing .reason');\n  }\n  return promise;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set status and reason together when instrumenting promises","Follow React's documented promise instrumentation recipe verbatim","Audit Promise patches and test mocks for status-only instrumentation"],"tags":["promise","suspense","use","instrumentation"],"backgroundTag":"instrumented-promise-missing-reason","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}