marmelab/react-admin · warning
When not redirecting after editing, query meta and mutation
Error message
When not redirecting after editing, query meta and mutation meta should be the same, or you will have data update issues.
What it means
useEditController warns when redirectTo === false but the queryOptions.meta and mutationOptions.meta passed to useEdit differ. Meta is used for optimistic-update cache matching; if query and mutation meta differ while staying on the same page, react-admin cannot reconcile the updated record with the cached query, causing stale or inconsistent displayed data.
Source
Thrown at packages/ra-core/src/controller/edit/useEditController.ts:106
'useEditController requires an id prop or a route with an /:id? parameter.'
);
}
const id = propsId ?? routeId;
const { meta: queryMeta, ...otherQueryOptions } = queryOptions;
const {
meta: mutationMeta,
onSuccess,
onError,
...otherMutationOptions
} = mutationOptions;
if (
(queryMeta || mutationMeta) &&
JSON.stringify(queryMeta) !== JSON.stringify(mutationMeta) &&
redirectTo === false
) {
console.warn(
'When not redirecting after editing, query meta and mutation meta should be the same, or you will have data update issues.'
);
}
const {
registerMutationMiddleware,
getMutateWithMiddlewares,
unregisterMutationMiddleware,
} = useMutationMiddlewares();
const {
data: record,
error,
isLoading,
isFetching,
isPaused,
isPending,
isPlaceholderData,
refetch,View on GitHub (pinned to 051f511bb0)
Solutions
- Make queryOptions.meta and mutationOptions.meta identical (same keys and values).
- If meta must differ, set a redirect target so the page remounts and the query refreshes.
- Remove meta from the side that doesn't need it so both are undefined.
Example fix
// before
useEdit({ redirect: false, queryOptions: { meta: { foo: 'bar' } }, mutationOptions: { meta: { baz: 'qux' } } });
// after
const meta = { foo: 'bar' };
useEdit({ redirect: false, queryOptions: { meta }, mutationOptions: { meta } }); Defensive patterns
Strategy: validation
Validate before calling
const meta = { tenantId: 't1' };
if (redirectTo === false) {
if (JSON.stringify(queryMeta) !== JSON.stringify(mutationMeta)) {
throw new Error('queryOptions.meta must equal mutationOptions.meta when redirect is false');
}
} Prevention
- Define meta once in a variable and reuse it for both queryOptions and mutationOptions.
- Keep meta JSON-serializable (no functions, Dates, or unstable values).
- Only use meta when your dataProvider actually needs it.
When it happens
Trigger: useEdit({ redirect: false, queryOptions: { meta: {...} }, mutationOptions: { meta: {...} } }) with the two meta objects not deep-equal (JSON.stringify comparison).
Common situations: Passing a meta containing timestamps, ids, or functions that differ per render; forgetting to mirror meta on mutationOptions when disabling redirect.
Related errors
- Invalid dataProvider response for create: missing id
- Found getManyReference result in cache without total or page
- useCanAccess must be used inside a <Resource> component or p
- useCreateController requires a non-empty resource prop or co
- useEditController requires a non-empty resource prop or cont
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/4903b01b998ba5e3.
Report an issue: GitHub.