marmelab/react-admin · error · Error

useEditController requires a non-empty resource prop or cont

Error message

useEditController requires a non-empty resource prop or context

What it means

useEditController drives the Edit view and must know which resource to query, redirect to, and authorize against. Like useCreateController, it resolves the resource via useResourceContext and throws when neither a `resource` prop nor a <Resource> context is available.

Source

Thrown at packages/ra-core/src/controller/edit/useEditController.ts:67

export const useEditController = <
    RecordType extends RaRecord = any,
    ErrorType = Error,
>(
    props: EditControllerProps<RecordType, ErrorType> = {}
): EditControllerResult<RecordType, ErrorType> => {
    const {
        disableAuthentication = false,
        id: propsId,
        mutationMode = 'undoable',
        mutationOptions = {},
        queryOptions = {},
        redirect: redirectTo = DefaultRedirect,
        redirectOnError = DefaultRedirectOnError,
        transform,
    } = props;
    const resource = useResourceContext(props);
    if (!resource) {
        throw new Error(
            'useEditController requires a non-empty resource prop or context'
        );
    }
    const { isPending: isPendingAuthenticated } = useAuthenticated({
        enabled: !disableAuthentication,
    });

    const { isPending: isPendingCanAccess } = useRequireAccess<RecordType>({
        action: 'edit',
        resource,
        enabled: !disableAuthentication && !isPendingAuthenticated,
    });

    const getRecordRepresentation = useGetRecordRepresentation(resource);
    const translate = useTranslate();
    const notify = useNotify();
    const redirect = useRedirect();
    const { id: routeId } = useParams<{ id?: string }>();

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Pass resource explicitly: `<Edit resource="posts" id={id}>` or `useEditController({ resource: 'posts', id })`.
  2. Mount the component under the proper <Resource name="posts" edit={...}> definition.
  3. If using a custom route, ensure the wrapping <Resource> provides the name context.
  4. Verify the resource variable is not empty due to a bad import or typo.

Example fix

// before
<CustomRoutes>
  <Edit id={id} /> {/* no resource context */}
</CustomRoutes>

// after
<CustomRoutes>
  <Edit resource="posts" id={id} />
</CustomRoutes>
Defensive patterns

Strategy: validation

Validate before calling

// Ensure resource presence before invoking the controller
const resource = props.resource ?? useResourceContext();
if (!resource) throw new Error('Edit view rendered without a resource; pass resource="..."');

Type guard

function hasResource(p: { resource?: string }): p is { resource: string } {
  return typeof p.resource === 'string' && p.resource.length > 0;
}

Try / catch

// Hook throws during render; guard before calling:
if (!hasResource(props)) return <MissingResource />;
const controller = useEditController(props);

Prevention

When it happens

Trigger: Rendering <Edit> (or calling useEditController) outside any <Resource> context without a resource prop, or with an empty/undefined resource prop.

Common situations: Custom edit pages mounted via <CustomRoutes> instead of <Resource name=... edit=...>; reusing Edit components in modals or tabs outside the Admin tree; refactoring that accidentally dropped the resource prop from a wrapper.

Related errors


AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30). Data as JSON: /api/errors/9b67d6f01ab08bcb. Report an issue: GitHub.