{"record":{"id":"8568328c868e8820","repo":"marmelab/react-admin","slug":"invalid-dataprovider-response-for-create-missing","errorCode":null,"errorMessage":"Invalid dataProvider response for create: missing id","messagePattern":"Invalid dataProvider response for create: missing id","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ra-core/src/dataProvider/useCreate.ts","lineNumber":150,"sourceCode":"    >(\n        { resource, ...params },\n        {\n            ...mutationOptions,\n            mutationKey: [resource, 'create', params],\n            mutationMode,\n            mutationFn: ({ resource, ...params }) =>\n                customMutationFnWithDataProviderResult(resource, params),\n            updateCache: (\n                { resource, ...params },\n                { mutationMode },\n                result\n            ) => {\n                const id =\n                    mutationMode === 'pessimistic'\n                        ? result?.id\n                        : params.data?.id;\n                if (id === undefined || id === null) {\n                    throw new Error(\n                        'Invalid dataProvider response for create: missing id'\n                    );\n                }\n                // hack: only way to tell react-query not to fetch this query for the next 5 seconds\n                // because setQueryData doesn't accept a stale time option\n                const now = Date.now();\n                const updatedAt =\n                    mutationMode === 'undoable' ? now + 5 * 1000 : now;\n                // Stringify and parse the data to remove undefined values.\n                // If we don't do this, an update with { id: undefined } as payload\n                // would remove the id from the record, which no real data provider does.\n                const clonedData = JSON.parse(\n                    JSON.stringify(\n                        mutationMode === 'pessimistic' ? result : params.data\n                    )\n                );\n\n                queryClient.setQueryData(","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-core/src/dataProvider/useCreate.ts#L132-L168","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ncreate: async (resource, params) => ({ data: params.data }),\n// after\ncreate: async (resource, params) => {\n  const { data } = await httpClient(`${apiUrl}/${resource}`, {\n    method: 'POST', body: JSON.stringify(params.data),\n  });\n  return { data: { ...params.data, ...data } }; // includes server id\n};","handlingStrategy":"type-guard","validationCode":"// wrap create so the response contract is checked before react-admin sees it\nconst safeCreate = async (resource, params) => {\n  const res = await dataProvider.create(resource, params);\n  if (res?.data?.id == null) throw new Error('dataProvider.create must return { data: { id } }');\n  return res;\n};","typeGuard":"const isCreatedRecord = (r: unknown): r is { data: { id: Identifier } } =>\n  typeof r === 'object' && r !== null && 'data' in r &&\n  typeof (r as any).data?.id !== 'undefined' && (r as any).data?.id !== null;","tryCatchPattern":"try {\n  await create('posts', { data });\n} catch (e) {\n  if (/Invalid dataProvider response for create: missing id/.test(e.message)) {\n    // fix provider: ensure the server returns and the provider echoes the generated id\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["react-admin","data-provider","create","cache","contract"],"backgroundTag":"invalid-data-provider-response","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}