facebook/react · error · Error
Expected counter to be known.
Error message
Expected counter to be known.
What it means
removeRootPseudoKey parses the root's pseudo key back into name and counter, then requires rootDisplayNameCounter to still have an entry for that name. The throw means the name/counter bookkeeping diverged - the counter map no longer matches the pseudo keys handed out earlier (e.g. re-mounts incremented counters without matching decrements, or the maps were rebuilt by a filter re-mount while a stale key remained).
Source
Thrown at packages/react-devtools-shared/src/backend/fiber/renderer.js:7797
const rootDisplayNameCounter: Map<string, number> = new Map();
function setRootPseudoKey(id: number, fiber: Fiber) {
const name = getDisplayNameForRoot(fiber);
const counter = rootDisplayNameCounter.get(name) || 0;
rootDisplayNameCounter.set(name, counter + 1);
const pseudoKey = `${name}:${counter}`;
rootPseudoKeys.set(id, pseudoKey);
}
function removeRootPseudoKey(id: number) {
const pseudoKey = rootPseudoKeys.get(id);
if (pseudoKey === undefined) {
throw new Error('Expected root pseudo key to be known.');
}
const name = pseudoKey.slice(0, pseudoKey.lastIndexOf(':'));
const counter = rootDisplayNameCounter.get(name);
if (counter === undefined) {
throw new Error('Expected counter to be known.');
}
if (counter > 1) {
rootDisplayNameCounter.set(name, counter - 1);
} else {
rootDisplayNameCounter.delete(name);
}
rootPseudoKeys.delete(id);
}
function getDisplayNameForRoot(fiber: Fiber): string {
let preferredDisplayName = null;
let fallbackDisplayName = null;
let child = fiber.child;
// Go at most three levels deep into direct children
// while searching for a child that has a displayName.
for (let i = 0; i < 3; i++) {
if (child === null) {
break;View on GitHub (pinned to eafeac097b)
Solutions
- Reload the page with DevTools open - counters are rebuilt consistently on a fresh session.
- Reduce concurrent filter toggling while roots mount/unmount.
- Upgrade DevTools/React to pick up counter bookkeeping fixes.
- Report with the sequence of filter toggles + root unmounts if it persists.
Defensive patterns
Strategy: fallback
Try / catch
// when embedding devtools-shared: counter map diverged from pseudo keys - reset session
try {
renderer.handleCommitFiberRoot(root, priorityLevel);
} catch (err) {
if (err.message.includes('Expected counter to be known')) {
location.reload(); // counters are session-local and rebuilt on fresh attach
} else {
throw err;
}
} Prevention
- Avoid rapid filter re-mount cycles in multi-root apps with shared display names.
- Prefer fresh DevTools sessions (reload) over very long-lived ones across many root cycles.
- Report deterministic repros to React.
When it happens
Trigger: Unmounting a root whose display-name counter entry is gone - typically after repeated filter re-mounts rewrote rootPseudoKeys/rootDisplayNameCounter while an old key survived, or duplicate teardown of the same display name.
Common situations: Repeatedly toggling component filters in multi-root apps (several roots with the same display name); fast refresh remount storms; long DevTools sessions across many root create/destroy cycles.
Related errors
- Expected root pseudo key to be known.
- Expected mounted root to have known pseudo key.
- Expected the root instance to exist when computing a path
- Expected a root instance to exist for this Fiber root
- Expected the root instance to already exist when starting pr
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/c8aeb2d834495187.
Report an issue: GitHub.