{"record":{"id":"dfd6242102d726e5","repo":"marmelab/react-admin","slug":"when-using-a-custom-resource-element-it-must-have","errorCode":null,"errorMessage":"When using a custom Resource element, it must have a static registerResource method accepting its props and returning a ResourceDefinition","messagePattern":"When using a custom Resource element, it must have a static registerResource method accepting its props and returning a ResourceDefinition","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ra-core/src/core/useConfigureAdminRouterFromChildren.tsx","lineNumber":218,"sourceCode":"const useRegisterResources = (\n    resources: (ReactElement & ResourceWithRegisterFunction)[],\n    permissions: any\n) => {\n    const { register, unregister } = useResourceDefinitionContext();\n\n    useEffect(() => {\n        resources.forEach(resource => {\n            if (\n                typeof (\n                    resource.type as unknown as ResourceWithRegisterFunction\n                ).registerResource === 'function'\n            ) {\n                const definition = (\n                    resource.type as unknown as ResourceWithRegisterFunction\n                ).registerResource(resource.props, permissions);\n                register(definition);\n            } else {\n                throw new Error(\n                    'When using a custom Resource element, it must have a static registerResource method accepting its props and returning a ResourceDefinition'\n                );\n            }\n        });\n        return () => {\n            resources.forEach(resource => {\n                if (\n                    typeof (\n                        resource.type as unknown as ResourceWithRegisterFunction\n                    ).registerResource === 'function'\n                ) {\n                    const definition = (\n                        resource.type as unknown as ResourceWithRegisterFunction\n                    ).registerResource(resource.props, permissions);\n                    unregister(definition);\n                } else {\n                    throw new Error(\n                        'When using a custom Resource element, it must have a static registerResource method accepting its props and returning a ResourceDefinition'","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-core/src/core/useConfigureAdminRouterFromChildren.tsx#L200-L236","documentation":"react-admin allows passing a custom element as a child of <Admin> in place of <Resource>. Such a custom component must expose a static registerResource(props, permissions) method that returns a ResourceDefinition, because useRegisterResources relies on it to build the resource definitions. When the child element's type has neither a name (standard Resource) nor a registerResource static, this error is thrown.","triggerScenarios":"Passing a custom React component as a direct child of <Admin> (or <AdminRouter>) whose component does not define `MyComponent.registerResource = (props, permissions) => ({ name, ... })`. Also occurs when permissions are provided and the component lacks the static method during re-registration on permission changes.","commonSituations":"Building custom resource wrappers or higher-order components around <Resource>; upgrading react-admin where resource children switched from name-based props to ResourceDefinition registration; TypeScript components declared without the static member so the cast fails at runtime.","solutions":["Add a static registerResource method to the custom component: `MyResource.registerResource = ({ name, ...props }, permissions) => ({ name, ...props });`","Alternatively use the standard `<Resource name=\"...\" list={...} />` element instead of a custom component","Type the component as `ResourceWithRegisterFunction` (FunctionComponent & { registerResource }) so TypeScript enforces the static method","If you only need custom props, keep <Resource> and configure it via its props rather than replacing it"],"exampleFix":"// before\nconst CustomResource = (props) => <Resource {...props} />;\n<Admin>{<CustomResource name=\"posts\" list={PostList} />}</Admin>\n\n// after\nconst CustomResource: ResourceWithRegisterFunction = (props) => <Resource {...props} />;\nCustomResource.registerResource = (props, permissions) => ({ name: props.name, list: props.list });\n<Admin><CustomResource name=\"posts\" list={PostList} /></Admin>","handlingStrategy":"validation","validationCode":"if (typeof CustomResource.registerResource !== 'function') {\n  throw new Error(`${CustomResource.name} must define a static registerResource method`);\n}","typeGuard":"const isResourceWithRegister = (el: any): el is React.ReactElement & { type: { registerResource: (props: any, permissions: any) => ResourceDefinition } } =>\n  React.isValidElement(el) && typeof (el.type as any)?.registerResource === 'function';","tryCatchPattern":null,"preventionTips":["Always define the static registerResource when creating custom resource child components","Model the component type as ResourceWithRegisterFunction so TypeScript enforces the static member","Prefer standard <Resource> unless registration customization is truly needed","Add a unit test rendering <Admin> with the custom resource child to catch regressions early"],"tags":["react-admin","resource-definition","missing-static-method","configuration"],"backgroundTag":"missing-static-registerresource","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}