facebook/relay · error · Error
NormalizationEngine: Expected the GraphQL @stream payload `d
Error message
NormalizationEngine: Expected the GraphQL @stream payload `data` value to be an object.
What it means
In _normalizeStreamItem, Relay destructures `data` from the incremental @stream response and requires it to be an object (the streamed item's fields). If `data` is a primitive, array-unexpectedly-null, or undefined (anything with typeof !== 'object'), Relay cannot normalize the item and throws.
Source
Thrown at packages/relay-runtime/store/NormalizationEngine.js:478
_normalizeStreamItem(
response: GraphQLResponseWithData,
parentID: string,
field: NormalizationLinkedField,
variables: Variables,
path: ReadonlyArray<unknown>,
normalizationPath: ReadonlyArray<string>,
): {
fieldPayloads: Array<HandleFieldPayload>,
itemID: string,
itemIndex: number,
prevIDs: Array<?string>,
relayPayload: RelayResponsePayload,
storageKey: string,
} {
const {data} = response;
if (typeof data !== 'object') {
throw err(
'NormalizationEngine: Expected the GraphQL @stream payload `data` ' +
'value to be an object.',
);
}
const responseKey = field.alias ?? field.name;
const storageKey = getStorageKey(field, variables);
const parentEntry = this._parentRecords.get(parentID);
if (parentEntry == null) {
throw err(
'NormalizationEngine: Expected the parent record `' +
parentID +
'` for @stream data to exist.',
);
}
const {fieldPayloads, record: parentRecord} = parentEntry;
const prevIDs = RelayModernRecord.getLinkedRecordIDs(View on GitHub (pinned to 668b1b85e0)
Solutions
- Inspect the raw streamed payload and confirm `data` is an object; if the server sends null with errors, handle/inspect the `errors` field instead of normalizing.
- Fix the server so each @stream part carries an object `data` (or omit the part when there is no data).
- Check the network layer's multipart parsing — ensure each chunk is parsed as complete JSON before being passed to the Relay environment.
- Check whether a proxy or fetch wrapper transforms the response body and strips/replaces `data`.
Example fix
// before
handleNextChunk(rawPart); // data may be null
// after
if (rawPart.data != null && typeof rawPart.data === 'object') {
handleNextChunk(rawPart);
} else {
handleError(rawPart.errors);
} Defensive patterns
Strategy: type-guard
Validate before calling
function hasObjectData(part) {
return part != null && typeof part.data === 'object' && part.data !== null;
}
if (!hasObjectData(streamPart)) { /* route to error handling instead of normalizing */ } Type guard
function isObjectPayload(res) {
return typeof res === 'object' && res !== null &&
'data' in res && typeof res.data === 'object' && res.data !== null;
} Try / catch
try {
normalizationEngine.processIncrementalResponse(response);
} catch (e) {
if (String(e.message).includes('@stream payload `data`')) {
handleStreamError(response.errors);
} else throw e;
} Prevention
- Ensure the server omits or error-handles stream parts instead of sending null data silently.
- Parse each multipart chunk as complete JSON before passing it to Relay.
- Beware proxies/transformers altering incremental payloads.
- Check the `errors` field of a part before normalizing data that may be null.
When it happens
Trigger: A @stream incremental payload arrives whose `data` value is not an object — e.g. the server sends `data: null` for an errored stream item, a scalar, or the network layer mangles the multipart part so data is missing.
Common situations: Servers sending null data alongside errors on streamed items; custom network layers parsing multipart chunks incorrectly (JSON fragments concatenated or truncated); proxies/transcoders altering incremental payloads.
Related errors
- NormalizationEngine: Expected incremental response to have `
- NormalizationEngine: Expected @stream to be used on a plural
- NormalizationEngine: Expected the parent record `${parentID}
- NormalizationEngine: Expected @stream field `${field.name}`
- BabelPluginRelay: Expected exactly one definition per graphq
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/2f49f4b151e3e0a3.
Report an issue: GitHub.