marmelab/react-admin · error
Label parameter must be a string, a ReactElement or false
Error message
Label parameter must be a string, a ReactElement or false
What it means
FieldTitle computes a field's label from the label/source props and translation. The `label` prop may be a string, a ReactElement, or false; passing `true` is invalid because there is no meaningful rendering for a boolean true label, so it throws immediately.
Source
Thrown at packages/ra-core/src/util/FieldTitle.tsx:18
import * as React from 'react';
import { ReactNode, memo } from 'react';
import { useTranslateLabel } from '../i18n';
export interface FieldTitleProps {
isRequired?: boolean;
resource?: string;
source?: string;
label?: ReactNode;
}
export const FieldTitle = (props: FieldTitleProps) => {
const { source, label, resource, isRequired } = props;
const translateLabel = useTranslateLabel();
if (label === true) {
throw new Error(
'Label parameter must be a string, a ReactElement or false'
);
}
if (label === false || label === '') {
return null;
}
if (label != null && typeof label !== 'string') {
return label;
}
return (
<span>
{translateLabel({
label,
resource,
source,View on GitHub (pinned to 051f511bb0)
Solutions
- Remove the label prop entirely to use the default (translated from source)
- Pass a concrete string: label="My label" or a translation element <label={<Translate i18nKey="..." />} />
- Pass label={false} to hide the label
- Fix the upstream value so booleans never reach label (coerce at the config boundary)
Example fix
// before
<TextInput source="name" label={showLabel} />
// after
<TextInput source="name" label={showLabel ? 'Name' : false} /> Defensive patterns
Strategy: validation
Validate before calling
const VALID = (v) => v === false || typeof v === 'string' || React.isValidElement(v) || v == null;
if (label != null && !VALID(label)) throw new Error('label must be string, element, or false'); Type guard
const isValidLabel = (label: unknown): label is string | React.ReactElement | false | undefined => label === false || label === undefined || typeof label === 'string' || React.isValidElement(label);
Try / catch
try {
setLabel(config.label);
} catch (e) {
if (e.message.includes('Label parameter must be')) {
setLabel(undefined); // fall back to default label
} else throw e;
} Prevention
- Type label as ReactElement | string | false in your config schemas
- Never pass raw booleans other than false as label
- Sanitize backend/CMS label config before mapping to input props
- Use the FieldTitleProps type so TS rejects label={true}
When it happens
Trigger: Passing label={true} (or a variable evaluating to true) to an input or field such as <TextInput source="x" label={true} />; spreading props where label came from untyped config/JSON containing true; TypeScript bypassed with `any` so the union type didn't catch it.
Common situations: Dynamic label configuration from backend/CMS values; conditional label logic like label={someCondition} that resolves to a boolean; migrating code where label was previously optional and someone used true as 'show label'.
Related errors
- useCreate mutation requires a resource
- useCreate mutation requires a non-empty data object
- useDelete mutation requires a resource
- useDelete mutation requires a non-empty id
- useDeleteMany mutation requires a resource
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/228e073a0ac32c61.
Report an issue: GitHub.