facebook/docusaurus · error · Error

Docusaurus error: Bad <Tabs> child <${badChildTypeName}>: al

Error message

Docusaurus error: Bad <Tabs> child <${badChildTypeName}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.
If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.

What it means

Thrown by the `<Tabs>` utility when one of its direct children is not a `<TabItem>` with a `value` prop. `Tabs` requires every child to be a `TabItem` (or to be recognizable as one) so it can build the tab list; any other element type is treated as a markup mistake.

Source

Thrown at packages/docusaurus-theme-common/src/utils/tabsUtils.tsx:81

  ): comp is ReactElement<TabItemProps> {
    const {props} = comp;
    return !!props && typeof props === 'object' && 'value' in props;
  }

  const elements = React.Children.toArray(children).flatMap((child) => {
    // Historical case, not sure when it happens, do we really need this?
    if (!child) {
      return [];
    }
    if (isValidElement(child) && isTabItemWithValueProp(child)) {
      return [child];
    }
    // child.type.name will give non-sensical values in prod because of
    // minification, but we assume it won't throw in prod.
    const badChildTypeName =
      // @ts-expect-error: guarding against unexpected cases
      typeof child.type === 'string' ? child.type : child.type.name;
    throw new Error(
      `Docusaurus error: Bad <Tabs> child <${badChildTypeName}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.
If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`,
    );
  });

  return elements.map(
    ({props: {value, label, attributes, default: isDefault}}) => ({
      value,
      label,
      attributes,
      default: isDefault,
    }),
  );
}

function ensureNoDuplicateValue(values: readonly TabValue[]) {
  const dup = duplicates(values, (a, b) => a.value === b.value);
  if (dup.length > 0) {

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Ensure every direct child of `<Tabs>` is a `<TabItem value="...">`.
  2. If you need non-tab scaffolding, move it outside `<Tabs>` or pass `values={[...]}` and render per-tab content via the values map.
  3. Re-check that no MDX implicit element (e.g. blank lines becoming `<p>`) slipped between TabItems.

Example fix

// before
<Tabs>
  <p>Pick one:</p>
  <TabItem label="A">A</TabItem>
</Tabs>
// after
<p>Pick one:</p>
<Tabs>
  <TabItem value="a" label="A">A</TabItem>
</Tabs>
Defensive patterns

Strategy: type-guard

Validate before calling

import {isValidElement} from 'react';
function isTabItemWithValue(child: any): boolean {
  return isValidElement(child) && child.type && (child.type as any).name === 'TabItem' && 'value' in (child.props ?? {});
}

Type guard

function isTabItemWithValueProp(child: unknown): child is React.ReactElement<{value: string}> {
  return React.isValidElement(child) && (child.type as any)?.name === 'TabItem' && typeof (child.props as any)?.value === 'string';
}

Prevention

When it happens

Trigger: Authoring MDX/JSX where `<Tabs>` wraps a `<div>`, plain text, `<p>`, or a `<TabItem>` that is missing its `value` prop. The bad child's type name is interpolated into the message (note: minified prod builds may show a mangled name).

Common situations: Forgetting `value` on a `TabItem`; wrapping helper elements (e.g. a heading) directly inside `<Tabs>`; copy-pasting tab markup that lost its props; MDX auto-wrapping stray text into a `<p>` inside Tabs.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/792de2681da34f36. Report an issue: GitHub.