marmelab/react-admin · error · Error
useDeleteMany mutation requires a resource
Error message
useDeleteMany mutation requires a resource
What it means
useDeleteMany wraps dataProvider.deleteMany in a react-query mutation. The mutate function accepts the resource as its first argument; if it is null or undefined, react-admin cannot know which resource to delete records from, so it throws immediately instead of calling the data provider. This is a programming-error guard against calling mutate() without a resource.
Source
Thrown at packages/ra-core/src/dataProvider/useDeleteMany.ts:104
>(
resource?: string,
params: Partial<DeleteManyParams<RecordType>> = {},
options: UseDeleteManyOptions<RecordType, MutationError> = {}
): UseDeleteManyResult<RecordType, MutationError> => {
const dataProvider = useDataProvider();
const queryClient = useQueryClient();
const {
mutationMode = 'pessimistic',
mutationFn: customMutationFn,
onSettled,
...mutationOptions
} = options;
const customMutationFnWithDataProviderResult = async (
resource: string | undefined,
params: Omit<UseDeleteManyMutateParams<RecordType>, 'resource'>
) => {
if (resource == null) {
throw new Error('useDeleteMany mutation requires a resource');
}
if (params.ids == null) {
throw new Error('useDeleteMany mutation requires an array of ids');
}
if (customMutationFn == null) {
return dataProvider.deleteMany<RecordType>(
resource,
params as DeleteManyParams<RecordType>
);
}
return {
data: await customMutationFn({ resource, ...params }),
};
};
const [mutate, mutationResult] = useMutationWithMutationMode<
MutationError,View on GitHub (pinned to 051f511bb0)
Solutions
- Pass the resource string as the first argument to mutate: mutate('posts', { ids }).
- If the resource comes from useResourceContext() or route params, render the component only inside the resource route or provide a default.
- Guard with an early check: if (!resource) return; before calling mutate.
Example fix
// before
const [deleteMany] = useDeleteMany();
deleteMany(resource, { ids }); // resource may be undefined
// after
const resource = useResourceContext();
const [deleteMany] = useDeleteMany();
if (resource) deleteMany(resource, { ids }); Defensive patterns
Strategy: validation
Validate before calling
if (typeof resource !== 'string' || resource.length === 0) {
throw new TypeError('useDeleteMany: resource must be a non-empty string');
} Type guard
const hasResource = (r: unknown): r is string => typeof r === 'string' && r.length > 0;
Try / catch
try {
await mutate(resource!, { ids });
} catch (e) {
if (e instanceof Error && e.message.includes('requires a resource')) {
notify('Cannot delete: no resource selected', { type: 'warning' });
} else throw e;
} Prevention
- Always source resource via useResourceContext() or an explicit prop.
- Render mutation-triggering components only inside a Resource route.
- Add a runtime check on resource in shared toolbar components.
When it happens
Trigger: Calling mutate(undefined, { ids: [...] }) or mutate(null, {...}); passing a resource variable that is undefined because it came from an unmatched route param or an uninitialized prop; destructuring useDeleteMany and invoking mutate before the resource prop is set.
Common situations: Dynamic resource names read from useParams() that are undefined outside the resource route; a custom list toolbar component reused outside a Resource context; refactoring that moved the mutate call to a place where the resource string is no longer in scope.
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 an array of ids
- useUpdate mutation requires a resource
- useUpdate mutation requires a non-empty id
- useUpdate mutation requires a non-empty data object
- useUpdateMany mutation requires a resource
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/54ce84bac236819c.
Report an issue: GitHub.