facebook/react · error · Error

Invalid internal instance: ${internalInstance}

Error message

Invalid internal instance: ${internalInstance}

What it means

In the legacy (React 15 stack reconciler) backend, getID() assigns stable numeric ids to internal instances and validates that the instance is a non-null object before using the id WeakMaps. The throw means traversal handed a primitive (string, number, null/undefined, boolean) where a composite or host internal instance was expected - DevTools could not even key the node.

Source

Thrown at packages/react-devtools-shared/src/backend/legacy/renderer.js:194

      // Not implemented.
      return null;
    };
    findHostInstanceForInternalID = (id: number) => {
      // Not implemented.
      return null;
    };
  }

  const supportsTogglingSuspense = false;

  function getDisplayNameForElementID(id: number): string | null {
    const internalInstance = idToInternalInstanceMap.get(id);
    return internalInstance ? getData(internalInstance).displayName : null;
  }

  function getID(internalInstance: InternalInstance): number {
    if (typeof internalInstance !== 'object' || internalInstance === null) {
      throw new Error('Invalid internal instance: ' + internalInstance);
    }
    if (!internalInstanceToIDMap.has(internalInstance)) {
      const id = getUID();
      internalInstanceToIDMap.set(internalInstance, id);
      idToInternalInstanceMap.set(id, internalInstance);
    }
    return internalInstanceToIDMap.get(internalInstance) as any as number;
  }

  function areEqualArrays(a: Array<any>, b: Array<any>) {
    if (a.length !== b.length) {
      return false;
    }
    for (let i = 0; i < a.length; i++) {
      if (a[i] !== b[i]) {
        return false;
      }
    }

View on GitHub (pinned to eafeac097b)

Solutions

  1. Disable other React-related extensions and any duplicate/embedded DevTools so only one backend patches React 15.
  2. Reload the page after disabling duplicates so the reconciler methods are patched exactly once.
  3. If you embed devtools-shared against React 15, filter children with getElementType(child) === ElementTypeOtherOrUnknown before touching ids (as the stock traversal does).
  4. Longer term, upgrade the app off React 15 - the legacy backend exists only for it.

Example fix

// before (custom traversal over legacy children)
const id = getID(child); // throws for raw text/null children

// after
if (typeof child === 'object' && child !== null && getElementType(child) !== ElementTypeOtherOrUnknown) {
  const id = getID(child);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// filter legacy children before touching ids, matching the stock traversal
const children = getChildren(instance).filter(
  child => typeof child === 'object' && child !== null,
);

Type guard

function isInternalInstance(value) {
  return typeof value === 'object' && value !== null;
}

Prevention

When it happens

Trigger: React 15 trees where _renderedChildren/_renderedComponent contain raw text/number nodes or nulls in a shape the backend did not filter out first, or another extension/monkey-patch altering the legacy Reconciler's arguments so args[0] is no longer the internal instance.

Common situations: Legacy React 15 apps inspected with modern DevTools; two React DevTools versions (extension + embedded) or other React tools (old perf tools) patching the same Reconciler methods; custom renderers imitating the React 15 legacy API incorrectly.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/75a932587cd7c571. Report an issue: GitHub.