marmelab/react-admin · error · Error
useUpdate mutation requires a non-empty data object
Error message
useUpdate mutation requires a non-empty data object
What it means
useUpdate requires a non-empty data object containing the fields to change. A falsy params.data (undefined, null, or empty object) gives the provider nothing to write, so the hook throws before calling dataProvider.update.
Source
Thrown at packages/ra-core/src/dataProvider/useUpdate.ts:114
...mutationOptions
} = options;
const dataProviderUpdate = useEvent(
(resource: string, params: UpdateParams<RecordType>) =>
dataProvider.update<RecordType>(resource, params)
);
const customMutationFnWithDataProviderResult = async (
resource: string | undefined,
params: Omit<UseUpdateMutateParams<RecordType>, 'resource'>
) => {
if (resource == null) {
throw new Error('useUpdate mutation requires a resource');
}
if (params.id == null) {
throw new Error('useUpdate mutation requires a non-empty id');
}
if (!params.data) {
throw new Error(
'useUpdate mutation requires a non-empty data object'
);
}
if (customMutationFn == null) {
return dataProviderUpdate(
resource,
params as UpdateParams<RecordType>
);
}
return {
data: await customMutationFn({ resource, ...params }),
};
};
const [mutate, mutationResult] = useMutationWithMutationMode<
ErrorType,
UpdateResult<RecordType>,View on GitHub (pinned to 051f511bb0)
Solutions
- Pass a populated payload: mutate('posts', { id, data: { title } }).
- Check Object.keys(data).length > 0 before calling mutate and skip the call otherwise.
- Verify form values are mapped into params.data, not another key.
Example fix
// before
update('posts', { id, data: values }); // values may be {}
// after
if (values && Object.keys(values).length > 0) update('posts', { id, data: values }); Defensive patterns
Strategy: validation
Validate before calling
if (!data || Object.keys(data).length === 0) {
throw new TypeError('useUpdate: data must be a non-empty object');
} Type guard
const hasData = (p: { data?: unknown }): p is { data: Record<string, unknown> } =>
typeof p.data === 'object' && p.data !== null && Object.keys(p.data).length > 0; Try / catch
try {
await mutate(resource, { id, data });
} catch (e) {
if (e instanceof Error && e.message.includes('non-empty data')) {
notify('No changes to save', { type: 'info' });
} else throw e;
} Prevention
- Skip the mutation when the form diff is empty (common with autosave).
- Map form values into params.data explicitly.
- Type the mutate params so a missing data key fails at compile time.
When it happens
Trigger: Calling mutate('posts', { id: 1 }) with no data; passing an object that is empty because form values were never populated; spreading a form values object that ends up {}.
Common situations: Autosave logic firing with an empty diff; form library returning an empty object on untouched forms; refactors that renamed the data key so the actual payload lands under a different property.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- useDeleteMany mutation requires a resource
- useDeleteMany mutation requires an array of ids
- useUpdate mutation requires a resource
- useUpdate mutation requires a non-empty id
- useUpdateMany mutation requires a resource
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/1f8dba4a794e95ad.
Report an issue: GitHub.