marmelab/react-admin · error · Error
Invalid dataProvider response for create: missing id
Error message
Invalid dataProvider response for create: missing id
What it means
After a create, react-admin needs the new record's id to update its cache. For pessimistic mode the id must come from the dataProvider response; for optimistic/undoable modes from params.data.id. If neither yields an id, the throw fires because the cache cannot be written correctly.
Source
Thrown at packages/ra-core/src/dataProvider/useCreate.ts:150
>(
{ resource, ...params },
{
...mutationOptions,
mutationKey: [resource, 'create', params],
mutationMode,
mutationFn: ({ resource, ...params }) =>
customMutationFnWithDataProviderResult(resource, params),
updateCache: (
{ resource, ...params },
{ mutationMode },
result
) => {
const id =
mutationMode === 'pessimistic'
? result?.id
: params.data?.id;
if (id === undefined || id === null) {
throw new Error(
'Invalid dataProvider response for create: missing id'
);
}
// hack: only way to tell react-query not to fetch this query for the next 5 seconds
// because setQueryData doesn't accept a stale time option
const now = Date.now();
const updatedAt =
mutationMode === 'undoable' ? now + 5 * 1000 : now;
// Stringify and parse the data to remove undefined values.
// If we don't do this, an update with { id: undefined } as payload
// would remove the id from the record, which no real data provider does.
const clonedData = JSON.parse(
JSON.stringify(
mutationMode === 'pessimistic' ? result : params.data
)
);
queryClient.setQueryData(View on GitHub (pinned to 051f511bb0)
Solutions
- Make dataProvider.create resolve with { data: { id: <generatedId>, ... } }
- Include an id in params.data when using optimistic/undoable mutation mode
- Use optimistic mode if your provider cannot return ids, supplying a client-side id
Example fix
// before
create: async (resource, params) => ({ data: params.data }),
// after
create: async (resource, params) => {
const { data } = await httpClient(`${apiUrl}/${resource}`, {
method: 'POST', body: JSON.stringify(params.data),
});
return { data: { ...params.data, ...data } }; // includes server id
}; Defensive patterns
Strategy: type-guard
Validate before calling
// wrap create so the response contract is checked before react-admin sees it
const safeCreate = async (resource, params) => {
const res = await dataProvider.create(resource, params);
if (res?.data?.id == null) throw new Error('dataProvider.create must return { data: { id } }');
return res;
}; Type guard
const isCreatedRecord = (r: unknown): r is { data: { id: Identifier } } =>
typeof r === 'object' && r !== null && 'data' in r &&
typeof (r as any).data?.id !== 'undefined' && (r as any).data?.id !== null; Try / catch
try {
await create('posts', { data });
} catch (e) {
if (/Invalid dataProvider response for create: missing id/.test(e.message)) {
// fix provider: ensure the server returns and the provider echoes the generated id
}
throw e;
} Prevention
- Assert create responses include an id in provider unit tests
- Never strip server-generated ids when mapping API responses
- In optimistic mode, generate a client-side id in params.data
When it happens
Trigger: A dataProvider.create resolving with a result lacking id (result?.id undefined/null) in pessimistic mode, or creating with params.data that has no id in optimistic/undoable mode.
Common situations: Custom data providers returning { data: { name } } without echoing a server-generated id; switching mutationMode to 'pessimistic' with a backend that doesn't return the id.
Related errors
- Unknown dataProvider function: ${type}
- The dataProvider threw an error. It should return a rejected
- useEditController: Fetched record's id attribute (${record.i
- useShowController: Fetched record's id attribute (${record.i
- create is not implemented
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/8568328c868e8820.
Report an issue: GitHub.