marmelab/react-admin · error · Error
Configurable must be used inside a PreferencesEditorContextP
Error message
Configurable must be used inside a PreferencesEditorContextProvider
What it means
Configurable opens the preferences editor via setEditor, which is only defined when a PreferencesEditorContextProvider (created by <Admin> with a UI enabling configuration, e.g. using <UIConfigurationEditor>/dark-layout config) wraps the tree. If the context exists but setEditor is missing, react-admin throws on click.
Source
Thrown at packages/ra-ui-materialui/src/preferences/Configurable.tsx:92
editorOpenRef.current = isEditorOpen;
}, [isEditorOpen]);
// on unmount, if selected, remove the editor
useEffect(() => {
return () => {
if (!editorOpenRef.current) return;
setPreferenceKey && setPreferenceKey(null);
setEditor && setEditor(null);
};
}, [setEditor, setPreferenceKey]);
if (!hasPreferencesEditorContext) {
return children;
}
const handleOpenEditor = () => {
if (!setEditor) {
throw new Error(
'Configurable must be used inside a PreferencesEditorContextProvider'
);
}
// include the editorKey as key to force destroy and mount
// when switching between two identical editors with different editor keys
// otherwise the editor will see an update and its useStore will return one tick later
// which would forbid the usage of uncontrolled inputs in the editor
setEditor(
cloneElement(editor, {
preferenceKey: prefixedPreferenceKey,
key: prefixedPreferenceKey,
})
);
if (!setPreferenceKey) {
throw new Error(
'Configurable must be used inside a PreferencesEditorContextProvider'
);View on GitHub (pinned to 051f511bb0)
Solutions
- Render the app inside <Admin> so the PreferencesEditorContextProvider is present.
- Remove or conditionally disable Configurable wrappers outside the admin shell.
- Wrap the subtree in PreferencesEditorContextProvider manually when embedding outside Admin.
Example fix
// before
render(<Configurable editor={<MyEditor />}>...</Configurable>);
// after
render(<Admin dataProvider={dp}><Configurable editor={<MyEditor />}>...</Configurable></Admin>); Defensive patterns
Strategy: validation
Validate before calling
const { setEditor } = usePreferencesEditorContext();
if (!setEditor) return children; // render non-configurable fallback Type guard
const hasPrefsEditor = (c: { setEditor?: unknown }): c is { setEditor: Function } => typeof c.setEditor === 'function'; Try / catch
try { openEditor(); } catch (e) { if (String(e).includes('PreferencesEditorContextProvider')) return; /* no-op outside admin */ throw e; } Prevention
- Use Configurable only inside <Admin>.
- In tests/storybook, wrap with the real provider.
- Guard the edit UI behind presence of setEditor.
When it happens
Trigger: Clicking a Configurable component's edit button when the component is rendered in an app (or route) not wrapped by the PreferencesEditorContextProvider.
Common situations: Using Configurable-wrapped components outside <Admin>, in tests, storybook, or custom entry points without the preferences editor setup.
Related errors
- 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
- DataTableRow can only be used within a RecordContext or be p
- DataTableRow can only be used within a ResourceContext or be
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/c6b4b79ce6bb02f5.
Report an issue: GitHub.