{"record":{"id":"d02d980bc3902b5d","repo":"facebook/relay","slug":"matchcontainer-expected-match-value-to-be-an-ob","errorCode":null,"errorMessage":"MatchContainer: Expected `match` value to be an object or null/undefined.","messagePattern":"MatchContainer: Expected `match` value to be an object or null/undefined\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/react-relay/relay-hooks/MatchContainer.js","lineNumber":111,"sourceCode":"  ...\n};\n\nexport type MatchContainerProps<\n  TProps extends {...},\n  TFallback extends React.Node,\n> = {\n  readonly fallback?: ?TFallback,\n  readonly loader: (module: unknown) => component(...TProps),\n  readonly match: ?MatchPointer | ?TypenameOnlyPointer,\n  readonly props?: TProps,\n};\n\ncomponent MatchContainer<\n  TProps extends {...},\n  TFallback extends React.Node | null,\n>(...{fallback, loader, match, props}: MatchContainerProps<TProps, TFallback>) {\n  if (match != null && typeof match !== 'object') {\n    throw new Error(\n      'MatchContainer: Expected `match` value to be an object or null/undefined.',\n    );\n  }\n  // NOTE: the MatchPointer type has a $fragmentSpreads field to ensure that only\n  // an object that contains a FragmentSpread can be passed. If the fragment\n  // spread matches, then the metadata fields below (__id, __fragments, etc.)\n  // will be present. But they can be missing if all the fragment spreads use\n  // @module and none of the types matched. The cast here is necessary because\n  // fragment Flow types don't describe metadata fields, only the actual schema\n  // fields the developer selected.\n  const {\n    __id,\n    __fragments,\n    __fragmentOwner,\n    __fragmentPropName,\n    __module_component,\n  } = (match as $FlowFixMe) ?? {};\n  if (","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/packages/react-relay/relay-hooks/MatchContainer.js#L93-L129","documentation":"MatchContainer renders results of @match/@moduleField-style loaded content and expects the `match` prop to be either null/undefined or an object carrying fragment-spread metadata. It throws synchronously during render when match is a non-object truthy value (string, number, boolean, etc.), guarding against passing raw data where a match pointer is required.","triggerScenarios":"Passing a primitive (string/number/boolean), array misuse, or some other non-object truthy value as the `match` prop of MatchContainer, e.g. <MatchContainer match={someString} .../> while match != null && typeof match !== 'object'.","commonSituations":"Wiring the wrong variable into `match` (e.g. the resolver's string key instead of the resolver result); a refactored resolver now returning a scalar; misusing MatchContainer outside a @match field context.","solutions":["Pass the resolver's returned object (the value Relay provides for @match fields) as `match`, not a scalar","Guard at the call site: only render MatchContainer when match is null or an object","Verify the parent fragment uses @match correctly so Relay supplies a proper match value"],"exampleFix":"// before\n<MatchContainer match={moduleKey} fallback={<Spinner />} />;\n\n// after\n<MatchContainer\n  match={typeof moduleKey === 'object' ? moduleKey : null}\n  fallback={<Spinner />}\n/>;","handlingStrategy":"type-guard","validationCode":"function validateMatch(match) {\n  if (match != null && typeof match !== 'object') {\n    throw new TypeError('match must be an object or null/undefined');\n  }\n  return match;\n}\n// usage: <MatchContainer match={validateMatch(value)} ... />","typeGuard":"const isMatchValue = (m) => m == null || (typeof m === 'object' && !Array.isArray(m));","tryCatchPattern":"try {\n  render(<MatchContainer match={value} fallback={<Spinner />} />);\n} catch (e) {\n  if (String(e.message).startsWith('MatchContainer:')) {\n    render(<Spinner />); // degrade gracefully on invalid match data\n  } else {\n    throw e;\n  }\n}","preventionTips":["Only pass values read from Relay @match resolver results to MatchContainer","Type the match prop strictly (MatchContainerProps) so primitives fail type-checking","Add prop-type/TS checks at boundaries where resolver data crosses modules"],"tags":["react","react-relay","render-time","runtime","type-mismatch"],"backgroundTag":"invalid-fragment-spread","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}