{"record":{"id":"74c3c9e05120b9e7","repo":"marmelab/react-admin","slug":"cannot-generate-a-link-for-a-record-without-a-reso","errorCode":null,"errorMessage":"Cannot generate a link for a record without a resource. You must use useGetPathForRecord within a ResourceContextProvider, or pass a resource prop.","messagePattern":"Cannot generate a link for a record without a resource\\. You must use useGetPathForRecord within a ResourceContextProvider, or pass a resource prop\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ra-core/src/routing/useGetPathForRecord.ts","lineNumber":50,"sourceCode":" * };\n *\n * // the link option can be a function returning a promise\n * const EditLink = ({ record, resource }) => {\n *   const path = useGetPathForRecord({ record, resource, link: async (record, resource) => {\n *     const canEdit = await canEditRecord(record, resource);\n *     return canEdit ? 'edit' : false;\n *   }});\n *   return path ? <Link to={path}>Edit</Link> : null;\n * };\n */\nexport const useGetPathForRecord = <RecordType extends RaRecord = RaRecord>(\n    options: UseGetPathForRecordOptions<RecordType> = {}\n): string | false | undefined => {\n    const { link } = options || {};\n    const record = useRecordContext(options);\n    const resource = useResourceContext(options);\n    if (!resource) {\n        throw new Error(\n            'Cannot generate a link for a record without a resource. You must use useGetPathForRecord within a ResourceContextProvider, or pass a resource prop.'\n        );\n    }\n    const resourceDefinition = useResourceDefinition(options);\n    const createPath = useCreatePath();\n    const [path, setPath] = useState<string | false>(\n        link && typeof link !== 'function' && record != null\n            ? createPath({\n                  resource,\n                  id: record.id,\n                  type: link,\n              })\n            : false\n    );\n\n    // in preparation for the default value, does the user have access to the show and edit pages?\n    // (we can't run hooks conditionally, so we need to run them even though the link is specified)\n    const { canAccess: canAccessShow } = useCanAccess({","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-core/src/routing/useGetPathForRecord.ts#L32-L68","documentation":"useGetPathForRecord computes the URL for a record using the resource context and resource definition hooks. If no resource is available — neither from props/options nor from a ResourceContextProvider (e.g. inside List/Edit) — react-admin throws because a record link cannot be generated without knowing the resource.","triggerScenarios":"Calling useGetPathForRecord({ record }) in a component outside any ResourceContextProvider without passing resource in options; rendering such a component directly on a custom page or in a test; options.resource typo'd or undefined at first render.","commonSituations":"Reusable RecordLink/TextField-derived components moved to a dashboard page (outside <List>/<Edit>); hooks consumed in modals portaled outside the resource tree; forgetting the resource prop on custom field components used outside resource pages.","solutions":["Pass resource explicitly: useGetPathForRecord({ resource: 'posts', record }).","Render the component inside a ResourceContextProvider (or a List/Edit/Show page that provides one).","Wrap with <ResourceContextProvider value=\"posts\"> for reusable components used on custom pages."],"exampleFix":"// before\nconst path = useGetPathForRecord({ record }); // throws on custom page\n\n// after\nimport { ResourceContextProvider } from 'react-admin';\n<ResourceContextProvider value=\"posts\">\n    <MyLink record={record} />\n</ResourceContextProvider>;\n// or\nconst path = useGetPathForRecord({ resource: 'posts', record });","handlingStrategy":"validation","validationCode":"const resource = useResourceContext(options);\nif (!resource) {\n    return null; // or render a fallback\n}\nconst path = useGetPathForRecord({ ...options, resource });","typeGuard":"const hasResource = (r: string | undefined | false): r is string => typeof r === 'string' && r.length > 0;","tryCatchPattern":"try {\n    path = useGetPathForRecord({ record });\n} catch (e) {\n    console.warn('useGetPathForRecord: no resource in context', e);\n    path = undefined;\n}","preventionTips":["Pass resource explicitly in reusable field/link components.","Wrap custom-page components with <ResourceContextProvider>.","Remember portal children don't inherit React context unless still in the React tree — keep them under the provider."],"tags":["routing","context","record"],"backgroundTag":"missing-required-argument","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}