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

  1. Log the raw incremental response before normalization and confirm the server includes `label` and `path` in every incremental part.
  2. If writing a custom network layer, ensure each incremental part is passed through verbatim (including extensions/path) instead of being reconstructed.
  3. Fix or upgrade the server's incremental delivery implementation to the spec so each payload has label and path.
  4. If mocking, include label/path in test fixtures: { data: ..., label: '<DeferLabel>', path: [...] }.
  5. 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

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


AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02). Data as JSON: /api/errors/e4a70e0e5aae3e34. Report an issue: GitHub.