{"record":{"id":"67096ae721f90f81","repo":"marmelab/react-admin","slug":"the-record-cannot-be-deleted-because-no-record-has","errorCode":null,"errorMessage":"The record cannot be deleted because no record has been passed","messagePattern":"The record cannot be deleted because no record has been passed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ra-core/src/controller/button/useDeleteController.tsx","lineNumber":130,"sourceCode":"                        ? error\n                        : error?.message || 'ra.notification.http_error',\n                    {\n                        type: 'error',\n                        messageArgs: {\n                            _:\n                                typeof error === 'string'\n                                    ? error\n                                    : error?.message,\n                        },\n                    }\n                );\n            },\n        }\n    );\n\n    const handleDelete = useCallback(() => {\n        if (!record) {\n            throw new Error(\n                'The record cannot be deleted because no record has been passed'\n            );\n        }\n        deleteOne(\n            resource,\n            {\n                id: record.id,\n                previousData: record,\n                meta: mutationMeta,\n            },\n            {\n                mutationMode,\n                ...otherMutationOptions,\n            }\n        );\n    }, [\n        deleteOne,\n        mutationMeta,","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-core/src/controller/button/useDeleteController.tsx#L112-L148","documentation":"useDeleteController's handleDelete callback needs the current record to know which id to delete. If no record was provided (record is undefined/null), the delete cannot identify a target, so it throws synchronously when the Delete button is clicked. Typically this means the component was rendered outside a record context.","triggerScenarios":"Clicking a <DeleteButton> rendered outside a <RecordContext>/list row so props.record is undefined; using useDeleteController directly without supplying a record; rendering DeleteButton in a Show/Edit page whose data hasn't loaded so record is still undefined when clicked (older versions).","commonSituations":"Custom toolbars rendering DeleteButton without record prop; buttons placed at page level instead of row level in a Datagrid; data still loading while the button is enabled.","solutions":["Render the button inside a RecordContext or pass record explicitly: <DeleteButton record={record} />","Disable the button until the record is loaded: <DeleteButton disabled={isLoading} />","If using useDeleteController directly, pass a record prop or guard the click handler"],"exampleFix":"// before\nconst MyToolbar = () => <DeleteButton />; // rendered outside record context\n// after\nconst MyToolbar = () => {\n    const record = useRecordContext();\n    if (!record) return null;\n    return <DeleteButton record={record} />;\n};","handlingStrategy":"validation","validationCode":"const record = useRecordContext();\nconst canDelete = Boolean(record && record.id != null);\n{canDelete && <DeleteButton record={record} />}","typeGuard":"const hasRecord = (r: unknown): r is { id: unknown } =>\n    r != null && typeof r === 'object' && 'id' in r;","tryCatchPattern":"try {\n    handleDelete();\n} catch (e) {\n    if (e instanceof Error && e.message.includes('no record has been passed')) {\n        notify('Cannot delete: record not loaded yet', { type: 'warning' });\n        return;\n    }\n    throw e;\n}","preventionTips":["Place delete buttons inside RecordContext (Show/Edit pages or Datagrid rows)","Disable or hide action buttons while the record query is loading","Pass record explicitly when rendering buttons outside standard contexts","In tests, always wrap buttons in a RecordContext with a fixture record"],"tags":["react","record","delete-button"],"backgroundTag":"missing-record-context","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}