react/react · error · Error

not implemented for work tag ${fiber.tag}

Error message

not implemented for work tag ${fiber.tag}

What it means

Thrown by isFiberHydrated() when it receives a Fiber whose tag is neither HostRoot nor SuspenseComponent. The function inspects a Fiber's memoizedState to determine hydration status, but only knows how to interpret those two work tags. Both call sites (renderer.js:3295 and :3359) guard on fiber.tag === SuspenseComponent before calling, so reaching the default branch means DevTools' internal call ordering is wrong or React introduced a new work tag that DevTools has not mapped yet. The function also throws 'not implemented for legacy suspense' when OffscreenComponent === -1 (old React without Offscreen), though that path is unreachable from the current call sites because they sit inside an OffscreenComponent !== -1 else-block.

Source

Thrown at packages/react-devtools-shared/src/backend/fiber/renderer.js:1024

  }

  function getEnvironmentNames(): Array<string> {
    return Array.from(knownEnvironmentNames);
  }

  function isFiberHydrated(fiber: Fiber): boolean {
    if (OffscreenComponent === -1) {
      throw new Error('not implemented for legacy suspense');
    }
    switch (fiber.tag) {
      case HostRoot:
        const rootState = fiber.memoizedState;
        return !rootState.isDehydrated;
      case SuspenseComponent:
        const suspenseState = fiber.memoizedState;
        return suspenseState === null || suspenseState.dehydrated === null;
      default:
        throw new Error('not implemented for work tag ' + fiber.tag);
    }
  }

  function shouldFilterVirtual(
    data: ReactComponentInfo,
    secondaryEnv: null | string,
  ): boolean {
    if (!isInFocusedActivity) {
      return true;
    }

    // For purposes of filtering Server Components are always Function Components.
    // Environment will be used to filter Server vs Client.
    // Technically they can be forwardRef and memo too but those filters will go away
    // as those become just plain user space function components like any HoC.
    if (hideElementsWithTypes.has(ElementTypeFunction)) {
      return true;
    }

View on GitHub (pinned to 22e4f993c7)

Solutions

  1. Update the React DevTools browser extension (or @react-devtools-core package) to the latest version matching your React build.
  2. Check whether your React version is canary/experimental — downgrade to a stable React release that DevTools fully supports.
  3. If embedding DevTools in a custom tool, verify the ReactTypeOfWork constants passed to the renderer match the React version being inspected.
  4. File a bug against react-devtools with the React version, DevTools version, and the numeric tag value that appeared in the message.
Defensive patterns

Strategy: type-guard

Validate before calling

// Before calling isFiberHydrated or processing a fiber tag:
const SUPPORTED_HYDRATION_TAGS = new Set([HostRoot, SuspenseComponent]);
if (OffscreenComponent !== -1 && SUPPORTED_HYDRATION_TAGS.has(fiber.tag)) {
  // safe to inspect hydration
  const hydrated = isFiberHydrated(fiber);
}

Type guard

function isHydrationSupportedTag(fiber: Fiber): boolean {
  return (
    OffscreenComponent !== -1 &&
    (fiber.tag === HostRoot || fiber.tag === SuspenseComponent)
  );
}

Prevention

When it happens

Trigger: isFiberHydrated is invoked with a Fiber whose .tag does not match HostRoot (3) or SuspenseComponent (13). This happens when React adds a new work tag constant that the installed DevTools version does not recognize, or when an internal DevTools refactor removes the SuspenseComponent guard before the call.

Common situations: Upgrading to a canary or experimental React build that introduces new component types before DevTools is updated; running a forked React with custom work tags; mixing React 18 DevTools with React 19+ runtime.

Related errors


AI-assisted analysis of react/react@22e4f993c7 (2026-08-12). Data as JSON: /api/errors/bc87581c5b8a018f. Report an issue: GitHub.