{"record":{"id":"6725c168330d1050","repo":"facebook/relay","slug":"normalizationengine-expected-stream-field-fie","errorCode":null,"errorMessage":"NormalizationEngine: Expected @stream field `${field.name}` to have a __typename.","messagePattern":"NormalizationEngine: Expected @stream field `(.+?)` to have a __typename\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/relay-runtime/store/NormalizationEngine.js","lineNumber":523,"sourceCode":"          field.name +\n          '` with @stream.',\n      );\n    }\n\n    const finalPathEntry = path[path.length - 1];\n    const itemIndex = parseInt(finalPathEntry, 10);\n    if (itemIndex !== finalPathEntry || itemIndex < 0) {\n      throw err(\n        'NormalizationEngine: Expected path for @stream to end in a ' +\n          'positive integer index, got `' +\n          String(finalPathEntry) +\n          '`',\n      );\n    }\n\n    const typeName = field.concreteType ?? (data as $FlowFixMe).__typename;\n    if (typeof typeName !== 'string') {\n      throw err(\n        'NormalizationEngine: Expected @stream field `' +\n          field.name +\n          '` to have a __typename.',\n      );\n    }\n\n    const getDataID = this._options.getDataID;\n    const itemID =\n      (typeof getDataID === 'function'\n        ? getDataID(data as $FlowFixMe, typeName)\n        : null) ??\n      prevIDs?.[itemIndex] ??\n      generateClientID(parentID, storageKey, itemIndex);\n    if (typeof itemID !== 'string') {\n      throw err(\n        'NormalizationEngine: Expected id of elements of field `' +\n          storageKey +\n          '` to be strings.',","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/packages/relay-runtime/store/NormalizationEngine.js#L505-L541","documentation":"To normalize a streamed item Relay must know its concrete type. It uses the field's concreteType (from a inline fragment/typed field in the query) when available, otherwise it falls back to the `__typename` in the streamed item's data. If neither yields a string, Relay cannot create a normalization selector and throws. This usually means the server omitted `__typename` from the streamed item or the query selected the field without a type.","triggerScenarios":"Normalizing a @stream item where field.concreteType is undefined AND the item data lacks a string `__typename` — e.g. the server doesn't echo __typename for streamed list items, or the query selects the streamed field without __typename and without a concrete type.","commonSituations":"Custom/older GraphQL servers that don't add __typename to incremental payloads, hand-rolled mock servers in tests forgetting __typename, or stripping __typename in a network-layer middleware (e.g. after apollo-link-style normalization).","solutions":["Add `__typename` to the selection set of the @stream field in your query","Fix the server/gateway to include __typename in streamed incremental payloads","Remove any middleware that deletes __typename from response data","If the type is statically known, ensure the compiled query provides concreteType for the field"],"exampleFix":"// before\nfragment F on Node { comments @stream { id text } }\n// after\nfragment F on Node { comments @stream { __typename id text } }","handlingStrategy":"validation","validationCode":"if (field.concreteType == null && typeof payload.data?.__typename !== 'string') {\n  throw new Error(`@stream field ${field.name} missing __typename`);\n}","typeGuard":"function hasTypename(d: unknown): d is { __typename: string } {\n  return typeof d === 'object' && d !== null && typeof (d as any).__typename === 'string';\n}","tryCatchPattern":null,"preventionTips":["Always select __typename on @stream fields","Never strip __typename in response middleware","Ensure the server echoes __typename in incremental payloads"],"tags":["relay","stream","typename","graphql"],"backgroundTag":"relay-stream-normalization","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}