{"record":{"id":"57b6ae36cfccbdd2","repo":"marmelab/react-admin","slug":"usecanaccess-must-be-used-inside-a-resource-comp","errorCode":null,"errorMessage":"useCanAccess must be used inside a <Resource> component or provide a resource prop","messagePattern":"useCanAccess must be used inside a <Resource> component or provide a resource prop","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ra-core/src/auth/useCanAccess.ts","lineNumber":60,"sourceCode":" *             return null;\n *         }\n *         if (error) {\n *             return <div>{error.message}</div>;\n *         }\n *         return <PostEdit />;\n *     };\n */\nexport const useCanAccess = <\n    RecordType extends Record<string, any> = Record<string, any>,\n    ErrorType extends Error = Error,\n>(\n    params: UseCanAccessOptions<RecordType, ErrorType>\n): UseCanAccessResult<ErrorType> => {\n    const authProvider = useAuthProvider();\n    const resource = useResourceContext(params);\n\n    if (!resource) {\n        throw new Error(\n            'useCanAccess must be used inside a <Resource> component or provide a resource prop'\n        );\n    }\n    const record = useRecordContext<RecordType>(params);\n    const { record: _record, ...restParams } = params;\n    const authProviderHasCanAccess = !!authProvider?.canAccess;\n\n    const queryResult = useQuery({\n        queryKey: [\n            'auth',\n            'canAccess',\n            { ...restParams, recordId: record?.id, resource },\n        ],\n        queryFn: async ({ signal }) => {\n            if (!authProvider || !authProvider.canAccess) {\n                return true;\n            }\n            return authProvider.canAccess({","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-core/src/auth/useCanAccess.ts#L42-L78","documentation":"useCanAccess performs permission checks against a specific resource, so it needs to know which resource to check. It resolves the resource via useResourceContext, which reads the resource prop or the surrounding <Resource> context. When neither exists, the library throws rather than silently returning a wrong authorization answer.","triggerScenarios":"Calling useCanAccess({ action, record }) outside any <Resource> context (e.g. in a standalone page, a layout, or before the router defines the resource) without passing a `resource` prop.","commonSituations":"Using useCanAccess in a custom dashboard/menu component rendered outside Resource definitions; rendering a permissions-gated component in Storybook or tests without wrapping it in <Resource name=\"...\">; forgetting to spread a resource prop through a custom wrapper.","solutions":["Pass the resource explicitly: `useCanAccess({ resource: 'posts', action: 'edit', record })`.","Move the component inside a <Resource name=\"posts\"> tree so useResourceContext resolves the resource.","In tests/Storybook, wrap the component with `<Resource name=\"posts\">` (inside an <Admin> or test AdminContext) to provide the context.","Fix custom wrapper components to forward the resource prop instead of dropping it."],"exampleFix":"// before\nconst { canAccess } = useCanAccess({ action: 'edit', record });\n\n// after\nconst { canAccess } = useCanAccess({ resource: 'posts', action: 'edit', record });","handlingStrategy":"validation","validationCode":"// Verify a resource is available before calling the hook\nconst resource = useResourceContext();\nif (!resource) {\n  console.warn('useCanAccess requires a resource prop or <Resource> context');\n}","typeGuard":"function hasResourceContext(params?: { resource?: string }): params is { resource: string } & typeof params {\n  return typeof params?.resource === 'string' && params.resource.length > 0;\n}","tryCatchPattern":"// React hooks cannot be wrapped in try/catch for render-time throws;\n// guard at the call site instead:\nconst resource = params.resource ?? useOptionalResourceContext?.();\nif (!resource) return null; // or render fallback\nconst { isPending, canAccess } = useCanAccess({ resource, action: 'edit', record });","preventionTips":["Always pass an explicit `resource` prop in reusable components.","Wrap standalone usages (tests, Storybook, dashboards) in <Resource name=\"...\">.","Keep permission-gated components inside the Admin/Resource tree.","Forward the resource prop in custom wrapper hooks instead of dropping it."],"tags":["react-admin","authorization","hooks","missing-context"],"backgroundTag":"missing-resource-context","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}