{"record":{"id":"8192d6fae01a6f04","repo":"marmelab/react-admin","slug":"useshowcontroller-requires-a-non-empty-resource-pr","errorCode":null,"errorMessage":"useShowController requires a non-empty resource prop or context","messagePattern":"useShowController requires a non-empty resource prop or context","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ra-core/src/controller/show/useShowController.ts","lineNumber":63,"sourceCode":" *     const controllerProps = useShowController({ resource: 'posts', id: 1234 });\n *     return <ShowView {...controllerProps} />;\n * };\n */\nexport const useShowController = <\n    RecordType extends RaRecord = any,\n    ErrorType = Error,\n>(\n    props: ShowControllerProps<RecordType, ErrorType> = {}\n): ShowControllerResult<RecordType, ErrorType> => {\n    const {\n        disableAuthentication = false,\n        id: propsId,\n        queryOptions = {},\n        redirectOnError = DefaultRedirectOnError,\n    } = props;\n    const resource = useResourceContext(props);\n    if (!resource) {\n        throw new Error(\n            `useShowController requires a non-empty resource prop or context`\n        );\n    }\n\n    const { isPending: isPendingAuthenticated } = useAuthenticated({\n        enabled: !disableAuthentication,\n    });\n\n    const { isPending: isPendingCanAccess } = useRequireAccess<RecordType>({\n        action: 'show',\n        resource,\n        enabled: !disableAuthentication && !isPendingAuthenticated,\n    });\n\n    const getRecordRepresentation = useGetRecordRepresentation(resource);\n    const translate = useTranslate();\n    const notify = useNotify();\n    const redirect = useRedirect();","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-core/src/controller/show/useShowController.ts#L45-L81","documentation":"useShowController (backing <Show>) needs a resource name to call dataProvider.getOne(). It resolves it from the `resource` prop or ResourceContext, and throws when neither provides a non-empty value.","triggerScenarios":"Rendering <Show> outside a <Resource> without a `resource` prop; dynamic route params missing so resource resolves to undefined; empty string resource.","commonSituations":"Custom show pages rendered standalone; tests/stories without ResourceContext; broken route definitions after renaming resources.","solutions":["Pass resource explicitly: <Show resource=\"posts\" id={123}>","Render inside a <Resource name=\"posts\"> route so the context supplies it","Fix routing so :resource/:id params resolve","Guard: return null or an error boundary when resource is falsy"],"exampleFix":"// before\nconst MyShow = () => <Show id={id} />;\n// after\nconst MyShow = () => <Show resource=\"posts\" id={id} />;\n// or inside routes:\n<Resource name=\"posts\" show={MyShow} />","handlingStrategy":"validation","validationCode":"const resource = props.resource ?? useResourceContext();\nif (!resource) throw new Error('Show requires a resource');\nreturn <Show resource={resource} id={id} />;","typeGuard":"const hasResource = (p: { resource?: string }): p is { resource: string } =>\n  typeof p.resource === 'string' && p.resource.length > 0;","tryCatchPattern":"try { return <Show resource={maybeResource} id={id} />; } catch (e) { if (String(e).includes('non-empty resource')) { return <NotFound />; } }","preventionTips":["Always render <Show> via <Resource show={...}> routes or pass resource","Validate route params (:resource, :id) before rendering","Wrap tests with ResourceContextProvider","Grep for bare `<Show ` without a resource attribute"],"tags":["react-admin","missing-props","context"],"backgroundTag":"missing-resource-context","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}