facebook/relay · error
The __id field must be present on each item passed to the se
Error message
The __id field must be present on each item passed to the setter. This indicates a bug in Relay.
What it means
Each item passed to a plural linked field setter must be a record proxy exposing a `__id` (data ID). This error fires when an item lacks `__id`, and Relay states it indicates a bug in Relay itself, since proxies returned by the library always carry it.
Source
Thrown at packages/relay-runtime/mutations/createUpdatableProxy.js:223
updatableProxyRootRecord: RecordProxy,
recordSourceProxy: RecordSourceProxy,
) {
return function set(newValue: ReadonlyArray<{__id: string, ...}>) {
const newVariables = getArgumentValues(selection.args ?? [], variables);
if (newValue == null) {
throw new Error(
'Do not assign null to plural linked fields; assign an empty array instead.',
);
} else {
const recordProxies = newValue.map((item): ?RecordProxy => {
if (item == null) {
throw new Error(
'When assigning an array of items, none of the items should be null or undefined.',
);
}
const {__id} = item;
if (__id == null) {
throw new Error(
'The __id field must be present on each item passed to the setter. This indicates a bug in Relay.',
);
}
const newValueRecord = recordSourceProxy.get(__id);
if (newValueRecord == null) {
throw new Error(
`Did not find item with data id ${__id} in the store.`,
);
}
return newValueRecord;
});
updatableProxyRootRecord.setLinkedRecords(
recordProxies,
selection.name,
newVariables,
);
}
};View on GitHub (pinned to 668b1b85e0)
Solutions
- Only pass records obtained from the updatable proxy (e.g. `updatable.viewer.friends.get()[0]`) or existing linked records into the setter
- Read the target records from `store.get(id)`/`recordSourceProxy.get(id)` rather than using raw response payloads
- If items come from another source, copy their fields into store records first, then assign those records
- If you are passing valid RecordProxies and still see this, file a bug with Relay — the message signals an internal invariant
Example fix
// before updatable.viewer.friends.set(response.updateUser.friends); // raw payload objects // after const updated = updatable.viewer.friends.get(); updatable.viewer.friends.set(updated); // record proxies from the store
Defensive patterns
Strategy: type-guard
Validate before calling
function isRecordProxyLike(item) {
return item != null && typeof item === 'object' && typeof item.__id === 'string' && item.__id.length > 0;
}
items.forEach(item => { if (!isRecordProxyLike(item)) throw new TypeError('Setter requires store record proxies with __id'); }); Type guard
function isRecordProxy(item: unknown): item is {__id: string} {
return typeof item === 'object' && item !== null && typeof (item as any).__id === 'string';
} Try / catch
try {
field.set(items);
} catch (e) {
if (e.message.includes('__id field must be present')) throw new Error('Pass record proxies from the updatable proxy/store, not raw payload objects', {cause: e});
throw e;
} Prevention
- Only assign records obtained from the updatable proxy, store.get, or existing linked records
- Never assign raw mutation/query response payloads directly
- Copy raw payload fields into store records first, then link those
- If valid proxies trigger this, file a Relay bug — it is an internal invariant
When it happens
Trigger: Passing raw plain objects (fetched manually or constructed inline) instead of RecordProxies from the updatable proxy into `pluralField.set(...)` — such objects have no `__id` property.
Common situations: Assigning raw mutation response objects instead of records read from the same updatable proxy; mixing records from a different RecordSource; a Relay internals regression.
Related errors
- The __id field must be present on the argument. This indicat
- Do not assign null to plural linked fields; assign an empty
- When assigning an array of items, none of the items should b
- BabelPluginRelay: Expected exactly one definition per graphq
- BabelPluginRelay: Expected a fragment, mutation, query, or s
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/e1a3be807b73a00b.
Report an issue: GitHub.