marmelab/react-admin · error · Error

<TranslatableFields> was called outside of a RecordContext a

Error message

<TranslatableFields> was called outside of a RecordContext and without a record prop. You must set the record prop.

What it means

<TranslatableFields> renders its children for each locale of the current record; without a record there is no data to translate, so it throws. The record normally comes from RecordContext (provided by Show/Edit/RecordContextProvider) or an explicit `record` prop.

Source

Thrown at packages/ra-ui-materialui/src/field/TranslatableFields.tsx:89

 * @param {ReactElement} props.selector The element responsible for selecting a locale. Defaults to Material UI tabs.
 */
export const TranslatableFields = (inProps: TranslatableFieldsProps) => {
    const props = useThemeProps({
        props: inProps,
        name: PREFIX,
    });
    const {
        defaultLocale,
        locales,
        groupKey = '',
        selector = <TranslatableFieldsTabs groupKey={groupKey} />,
        children,
        className,
        resource: resourceProp,
    } = props;
    const record = useRecordContext(props);
    if (!record) {
        throw new Error(
            `<TranslatableFields> was called outside of a RecordContext and without a record prop. You must set the record prop.`
        );
    }
    const resource = useResourceContext(props);
    if (!resource) {
        throw new Error(
            `<TranslatableFields> was called outside of a ResourceContext and without a record prop. You must set the resource prop.`
        );
    }
    const context = useTranslatable({ defaultLocale, locales });

    return (
        <Root className={className}>
            <TranslatableContextProvider value={context}>
                {selector}
                {locales.map(locale => (
                    <TranslatableFieldsTabContent
                        key={locale}

View on GitHub (pinned to 051f511bb0)

Solutions

  1. Wrap it in a RecordContextProvider or render inside <Show>/<Edit>: `<RecordContextProvider value={record}><TranslatableFields locales={[...]}>...</TranslatableFields></RecordContextProvider>`.
  2. Pass a `record` prop explicitly: `<TranslatableFields record={myRecord} locales={...}>`.
  3. If there is no record yet (create), guard rendering until a record is available.

Example fix

// before
<TranslatableFields locales={['en', 'fr']}>
  <TextField source="title" />
</TranslatableFields>

// after
<RecordContextProvider value={record}>
  <TranslatableFields locales={['en', 'fr']}>
    <TextField source="title" />
  </TranslatableFields>
</RecordContextProvider>
Defensive patterns

Strategy: validation

Validate before calling

if (!record) return null; // or render a placeholder before mounting TranslatableFields

Type guard

const hasRecord = (p: { record?: RaRecord }): p is typeof p & { record: RaRecord } => p.record != null;

Prevention

When it happens

Trigger: Rendering <TranslatableFields> outside a RecordContext (not inside <Show>/<Edit>/List row) and without a `record` prop; useRecordContext(props) returns undefined.

Common situations: Using TranslatableFields in a custom page or create form where no record exists yet; rendering it in isolation in a story/test; placing it outside the Show/Edit layout that supplies the record.

Related errors


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