marmelab/react-admin · error · Error
useUpdateMany mutation requires a non-empty data object
Error message
useUpdateMany mutation requires a non-empty data object
What it means
useUpdateMany requires params.data to be a truthy, non-empty object since there is nothing to update otherwise. The hook throws synchronously when data is falsy (undefined, null, empty object is truthy so undefined/null are the usual culprits).
Source
Thrown at packages/ra-core/src/dataProvider/useUpdateMany.ts:110
...mutationOptions
} = options;
const dataProviderUpdateMany = useEvent(
(resource: string, params: UpdateManyParams<RecordType>) =>
dataProvider.updateMany<RecordType>(resource, params)
);
const customMutationFnWithDataProviderResult = async (
resource: string | undefined,
params: Omit<UseUpdateManyMutateParams<RecordType>, 'resource'>
) => {
if (resource == null) {
throw new Error('useUpdateMany mutation requires a resource');
}
if (params.ids == null) {
throw new Error('useUpdateMany mutation requires an array of ids');
}
if (!params.data) {
throw new Error(
'useUpdateMany mutation requires a non-empty data object'
);
}
if (customMutationFn == null) {
return dataProviderUpdateMany(
resource,
params as UpdateManyParams<RecordType>
);
}
return {
data: await customMutationFn({ resource, ...params }),
};
};
const [mutate, mutationResult] = useMutationWithMutationMode<
MutationError,
UpdateManyResult<RecordType>,View on GitHub (pinned to 051f511bb0)
Solutions
- Ensure a non-empty data object is passed: mutate({ ids, data: { field: value } }).
- Guard the call with if (data && Object.keys(data).length > 0).
- If the intent is to update one field, hardcode the payload rather than deriving it from possibly-empty state.
- Check that form defaultValues are set so submitted values are never undefined.
Example fix
// before
mutate({ ids, data: updates }); // updates undefined when form untouched
// after
const updates = { status: 'archived', ...formValues };
if (ids.length && Object.keys(updates).length) {
mutate({ ids, data: updates });
} Defensive patterns
Strategy: validation
Validate before calling
const canUpdate = ids.length > 0 && data != null && Object.keys(data).length > 0;
if (canUpdate) mutate({ ids, data }); Type guard
const hasData = (p: { data?: unknown }): p is { data: Record<string, unknown> } =>
p.data != null && typeof p.data === 'object'; Try / catch
try {
mutate({ ids, data });
} catch (e) {
if (e instanceof Error && e.message.includes('non-empty data object')) {
notify('No changes to apply', { type: 'warning' });
}
} Prevention
- Never derive data solely from possibly-uninitialized form state.
- Provide defaultValues in bulk-edit forms.
- Assert the payload object has keys before mutating.
- Log the payload in development before calling mutate.
When it happens
Trigger: Calling mutate({ ids, data: undefined }) or data built conditionally (e.g. from an empty form values object that was never set).
Common situations: Bulk edit dialogs where the form submit passes uninitialized values; refactored code where data was moved into another variable; passing only ids and forgetting data entirely.
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
- useUpdateMany mutation requires an array of ids
- useCreate mutation requires a resource
- useCreate mutation requires a non-empty data object
- useDelete mutation requires a resource
- useDelete mutation requires a non-empty id
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/cd74057786483525.
Report an issue: GitHub.