{"record":{"id":"701dc41a6662a09a","repo":"marmelab/react-admin","slug":"cannot-generate-a-link-for-a-record-without-a-reso-701dc4","errorCode":null,"errorMessage":"Cannot generate a link for a record without a resource. You must use useGetPathForRecordCallback within a ResourceContextProvider, or pass a resource parameter.","messagePattern":"Cannot generate a link for a record without a resource\\. You must use useGetPathForRecordCallback within a ResourceContextProvider, or pass a resource parameter\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ra-core/src/routing/useGetPathForRecordCallback.ts","lineNumber":24,"sourceCode":"import { useCreatePath } from './useCreatePath';\nimport { UseGetRouteForRecordOptions } from './useGetPathForRecord';\n\nexport const useGetPathForRecordCallback = <\n    RecordType extends RaRecord = RaRecord,\n>(\n    options: UseGetPathForRecordCallbackOptions = {}\n) => {\n    const resource = useResourceContext(options);\n    const resourceDefinitions = useResourceDefinitions();\n    const createPath = useCreatePath();\n    const canAccess = useCanAccessCallback();\n\n    return useCallback(\n        async (params: UseGetRouteForRecordOptions<RecordType>) => {\n            const { link, record } = params || {};\n            const finalResource = params.resource ?? resource;\n            if (!finalResource) {\n                throw new Error(\n                    'Cannot generate a link for a record without a resource. You must use useGetPathForRecordCallback within a ResourceContextProvider, or pass a resource parameter.'\n                );\n            }\n            const resourceDefinition = resourceDefinitions[finalResource] ?? {};\n\n            if (record == null || link === false) {\n                return false;\n            }\n\n            // When the link prop is not provided, we infer a default value and check whether users\n            // can access it\n            if (link == null) {\n                // check if the user can access the show and edit pages in parallel\n                const [canAccessShow, canAccessEdit] = await Promise.all([\n                    resourceDefinition.hasShow\n                        ? canAccess({\n                              action: 'show',\n                              resource: finalResource,","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-core/src/routing/useGetPathForRecordCallback.ts#L6-L42","documentation":"useGetPathForRecordCallback returns a callback that resolves a record's URL. Inside the callback it resolves the resource from the params, or falls back to the resource captured from the ResourceContext at hook time. When neither exists it throws, since generating a record link requires a resource name.","triggerScenarios":"Invoking the returned callback with ({ record }) and no resource in params while the hook was called outside a ResourceContextProvider; the resource prop/context being undefined at callback time (data not loaded); calling the callback on a custom page without resource context.","commonSituations":"Reusable row-link logic used on a dashboard; portaled components losing the ResourceContext; async handlers built at mount when context hadn't resolved; forgetting the resource key in the callback params object.","solutions":["Include resource in the callback params: getPath({ resource: 'posts', record }).","Call the hook (and thus capture the context resource) inside a ResourceContextProvider subtree.","Guard the call: only invoke the callback once the resource is known, or provide a default resource."],"exampleFix":"// before\nconst getPath = useGetPathForRecordCallback();\nconst url = await getPath({ record }); // throws outside resource context\n\n// after\nconst url = await getPath({ resource: 'posts', record });","handlingStrategy":"validation","validationCode":"const getPath = useGetPathForRecordCallback();\nconst safeGetPath = (params) =>\n    (params.resource ?? resource)\n        ? getPath(params)\n        : undefined;\nconst url = await safeGetPath({ record });","typeGuard":"const hasResourceParam = (p: { resource?: string }) => typeof p.resource === 'string' && p.resource.length > 0;","tryCatchPattern":"try {\n    url = await getPath({ record });\n} catch (e) {\n    console.warn('No resource for record path', e);\n    url = undefined;\n}","preventionTips":["Always include resource in the callback params when used outside resource pages.","Capture the context resource at hook time by calling the hook inside a ResourceContextProvider.","Await the callback only after the record and resource are resolved."],"tags":["routing","context","record","callback"],"backgroundTag":"missing-required-argument","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}