facebook/relay · error · Error
NormalizationEngine: Expected incremental response to have `
Error message
NormalizationEngine: Expected incremental response to have `label` and `path` properties.
What it means
Relay's NormalizationEngine processes incremental (defer/stream) responses and requires each incremental payload to carry `label` and `path`. These identify which deferred fragment and where in the response tree the payload belongs. When an incremental response arrives without either property, Relay cannot route the data into the store and throws immediately.
Source
Thrown at packages/relay-runtime/store/NormalizationEngine.js:223
pendingModules,
};
}
/**
* Process an incremental response (@defer chunk or @stream item).
* Matches the response to a registered placeholder by label + path.
*
* Returns null if the response was buffered (no placeholder yet).
* Otherwise returns payloads array and pending module Promises.
*/
processIncrementalResponse(
response: GraphQLResponseWithData,
): ?NormalizationResult {
const label: ?string = response.label;
const path: ?ReadonlyArray<string | number> = response.path;
if (label == null || path == null) {
throw err(
'NormalizationEngine: Expected incremental response to have ' +
'`label` and `path` properties.',
);
}
const isDefer = label.indexOf('$defer$') !== -1;
const pathKey = isDefer
? path.map(String).join('.')
: path.slice(0, -2).map(String).join('.');
const key = makeKey(label, pathKey);
const placeholder = this._placeholders.get(key);
if (placeholder == null) {
// Buffer: response arrived before placeholder was registered
let buffer = this._bufferedResponses.get(key);
if (buffer == null) {
buffer = [];View on GitHub (pinned to 668b1b85e0)
Solutions
- Log the raw incremental response before normalization and confirm the server includes `label` and `path` in every incremental part.
- If writing a custom network layer, ensure each incremental part is passed through verbatim (including extensions/path) instead of being reconstructed.
- Fix or upgrade the server's incremental delivery implementation to the spec so each payload has label and path.
- If mocking, include label/path in test fixtures: { data: ..., label: '<DeferLabel>', path: [...] }.
- Check that no middleware strips `label`/`path` fields from response parts.
Example fix
// before
normalizationEngine.processIncrementalResponse({ data: item.data });
// after
normalizationEngine.processIncrementalResponse({
data: item.data,
label: item.label,
path: item.path,
}); Defensive patterns
Strategy: validation
Validate before calling
function isValidIncrementalResponse(res) {
return res != null && res.label != null && res.path != null && typeof res.data === 'object' && res.data !== null;
}
if (!isValidIncrementalResponse(response)) throw new Error('Invalid incremental response'); Type guard
function hasLabelAndPath(res) {
return typeof res === 'object' && res !== null &&
typeof res.label === 'string' && Array.isArray(res.path);
} Try / catch
try {
normalizationEngine.processIncrementalResponse(response);
} catch (e) {
if (String(e.message).includes('`label` and `path`')) {
console.error('Malformed incremental payload from network layer:', response);
} else throw e;
} Prevention
- Validate multipart incremental payloads in your network layer before handing them to Relay.
- Keep the server's incremental delivery implementation spec-compliant (label + path on every part).
- Include label/path in all mocked incremental responses.
- Avoid middleware that rewrites or strips response fields.
When it happens
Trigger: Calling `processIncrementalResponse` with a `GraphQLResponseWithData` object whose `label` or `path` is null/undefined — typically because a custom network layer split or forwarded the raw multipart payload incorrectly, or the server emitted an incremental part missing those fields.
Common situations: Custom Relay network handlers that mishandle @defer/@stream multipart responses; servers (or proxies) with non-conformant incremental delivery implementations; upgrading Relay while using an old server that predates the incremental-delivery spec fields; manually replaying/mocking incremental responses in tests without label/path.
Related errors
- NormalizationEngine: Expected @stream to be used on a plural
- NormalizationEngine: Expected the GraphQL @stream payload `d
- NormalizationEngine: Expected the parent record `${parentID}
- NormalizationEngine: Expected path for @stream to end in a p
- NormalizationEngine: Expected @stream field `${field.name}`
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/e4a70e0e5aae3e34.
Report an issue: GitHub.