facebook/relay · error
LiveResolverCache: `ServerWeak` normalization info must not
Error message
LiveResolverCache: `ServerWeak` normalization info must not be normalized; it is read in place off the transplanted record.
What it means
In LiveResolverCache's normalization switch, the 'ServerWeak' case is unreachable by design: ServerWeak values are read in place from a transplanted record and are short-circuited by _setResolverValue before normalization. Reaching this throw indicates an internal invariant was violated, not a user error.
Source
Thrown at packages/relay-runtime/store/live-resolvers/LiveResolverCache.js:877
// inner model instance: the model's field resolvers are wired via
// `resolverDataInjector(..., '__relay_model_instance', ...)`, which reads
// `MODEL_PROPERTY_NAME` and passes it to the resolver as the model — so
// storing the wrapper would make every field resolve to `undefined`.
const record = RelayModernRecord.create(outputTypeDataID, typename);
const modelValue =
MODEL_PROPERTY_NAME in value ? value[MODEL_PROPERTY_NAME] : value;
RelayModernRecord.setValue(record, MODEL_PROPERTY_NAME, modelValue);
source.set(outputTypeDataID, record);
return source;
}
case 'ServerWeak': {
// A read-in-place shadow server-value arm is never normalized:
// `_setResolverValue` short-circuits before reaching here, because the
// value is already normalized once by the magic-fragment transplant.
// Reaching this case would mean that guard was bypassed.
throw new Error(
'LiveResolverCache: `ServerWeak` normalization info must not be ' +
'normalized; it is read in place off the transplanted record.',
);
}
default:
normalizationInfo.kind as empty;
invariant(
false,
'LiveResolverCache: Unexpected normalization info kind `%s`.',
normalizationInfo.kind,
);
}
}
// If a given record does not exist, creates an empty record consisting of
// just an `id` field, along with a namespaced `__id` field and insert it into
// the store.
ensureClientRecord(id: string, typeName: string): DataID {View on GitHub (pinned to 668b1b85e0)
Solutions
- Align all relay-related package versions (react-relay, relay-runtime, relay-test-utils) to the same release
- Remove custom subclasses/patches around LiveResolverCache and use the public API
- Report with a reproduction to facebook/relay if it occurs on a single consistent version — this is an internal invariant failure
- As a workaround, disable experimental live resolvers to avoid the code path
Example fix
// before "relay-runtime": "13.2.0", "react-relay": "14.1.0" // mismatched internals // after "relay-runtime": "14.1.0", "react-relay": "14.1.0"
Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try {
readViaLiveResolverCache();
} catch (e) {
if (String(e.message).includes('ServerWeak')) {
console.error('Internal LiveResolverCache invariant violated; check relay package version alignment');
} else throw e;
} Prevention
- Keep relay-runtime and react-relay on identical versions
- Don't subclass or patch LiveResolverCache internals
- Avoid experimental live resolver paths unless needed
- Reproduce and report invariant failures upstream
When it happens
Trigger: An internal bug or version mismatch bypassing the _setResolverValue short-circuit so a ServerWeak resolver value reaches getNormalized resolver code — e.g. mixing relay-runtime versions of live-resolver internals, or custom cache subclasses routing values through normalization directly.
Common situations: Mismatched relay/react-relay package versions where LiveResolverCache internals disagree; monkey-patching or subclassing LiveResolverCache; a genuine Relay bug after upgrading.
Related errors
- BabelPluginRelay: Expected plugin context to include "types"
- BabelPluginRelay: Expected exactly one definition per graphq
- BabelPluginRelay: Expected a fragment, mutation, query, or s
- GraphQL operations and fragments must contain names
- Babel state is missing expected file name
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/7c405bc217b74eed.
Report an issue: GitHub.