{"record":{"id":"0e6e88a7560141aa","repo":"marmelab/react-admin","slug":"useupdate-mutation-requires-a-non-empty-id","errorCode":null,"errorMessage":"useUpdate mutation requires a non-empty id","messagePattern":"useUpdate mutation requires a non-empty id","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ra-core/src/dataProvider/useUpdate.ts","lineNumber":111,"sourceCode":"        mutationMode = 'pessimistic',\n        getMutateWithMiddlewares,\n        mutationFn: customMutationFn,\n        ...mutationOptions\n    } = options;\n\n    const dataProviderUpdate = useEvent(\n        (resource: string, params: UpdateParams<RecordType>) =>\n            dataProvider.update<RecordType>(resource, params)\n    );\n    const customMutationFnWithDataProviderResult = async (\n        resource: string | undefined,\n        params: Omit<UseUpdateMutateParams<RecordType>, 'resource'>\n    ) => {\n        if (resource == null) {\n            throw new Error('useUpdate mutation requires a resource');\n        }\n        if (params.id == null) {\n            throw new Error('useUpdate mutation requires a non-empty id');\n        }\n        if (!params.data) {\n            throw new Error(\n                'useUpdate mutation requires a non-empty data object'\n            );\n        }\n        if (customMutationFn == null) {\n            return dataProviderUpdate(\n                resource,\n                params as UpdateParams<RecordType>\n            );\n        }\n\n        return {\n            data: await customMutationFn({ resource, ...params }),\n        };\n    };\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-core/src/dataProvider/useUpdate.ts#L93-L129","documentation":"useUpdate's mutate requires a non-null id of the record to update. When params.id is null or undefined the target record is unknown, so the hook throws before calling dataProvider.update.","triggerScenarios":"Calling mutate('posts', { id: undefined, data }); the record loaded asynchronously so record.id is undefined at call time; passing a record object instead of its id.","commonSituations":"Save button clicked before the record query resolves; forms using getValues() on an empty form; passing the whole record ({ ...record }) where id is missing due to a misconfigured provider that omits the id field.","solutions":["Pass the record id: mutate('posts', { id: record.id, data }).","Disable save actions while the record query is loading.","Verify the data provider returns an id field for every record."],"exampleFix":"// before\nupdate('posts', { id: record?.id, data }); // may be undefined\n// after\nif (record?.id != null) update('posts', { id: record.id, data });","handlingStrategy":"validation","validationCode":"if (id == null) {\n  throw new TypeError('useUpdate: id must be provided');\n}","typeGuard":"const hasId = (p: { id?: unknown }): p is { id: string | number } =>\n  p.id != null;","tryCatchPattern":"try {\n  await mutate(resource, { id: record!.id, data });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('non-empty id')) {\n    notify('No record loaded to update', { type: 'warning' });\n  } else throw e;\n}","preventionTips":["Disable save controls while the record query isLoading.","Pass record.id, never the record object itself.","Ensure data providers always include an id on records."],"tags":["react-admin","mutation","missing-argument","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}