{"record":{"id":"c8aeb2d834495187","repo":"facebook/react","slug":"expected-counter-to-be-known","errorCode":null,"errorMessage":"Expected counter to be known.","messagePattern":"Expected counter to be known\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-devtools-shared/src/backend/fiber/renderer.js","lineNumber":7797,"sourceCode":"  const rootDisplayNameCounter: Map<string, number> = new Map();\n\n  function setRootPseudoKey(id: number, fiber: Fiber) {\n    const name = getDisplayNameForRoot(fiber);\n    const counter = rootDisplayNameCounter.get(name) || 0;\n    rootDisplayNameCounter.set(name, counter + 1);\n    const pseudoKey = `${name}:${counter}`;\n    rootPseudoKeys.set(id, pseudoKey);\n  }\n\n  function removeRootPseudoKey(id: number) {\n    const pseudoKey = rootPseudoKeys.get(id);\n    if (pseudoKey === undefined) {\n      throw new Error('Expected root pseudo key to be known.');\n    }\n    const name = pseudoKey.slice(0, pseudoKey.lastIndexOf(':'));\n    const counter = rootDisplayNameCounter.get(name);\n    if (counter === undefined) {\n      throw new Error('Expected counter to be known.');\n    }\n    if (counter > 1) {\n      rootDisplayNameCounter.set(name, counter - 1);\n    } else {\n      rootDisplayNameCounter.delete(name);\n    }\n    rootPseudoKeys.delete(id);\n  }\n\n  function getDisplayNameForRoot(fiber: Fiber): string {\n    let preferredDisplayName = null;\n    let fallbackDisplayName = null;\n    let child = fiber.child;\n    // Go at most three levels deep into direct children\n    // while searching for a child that has a displayName.\n    for (let i = 0; i < 3; i++) {\n      if (child === null) {\n        break;","sourceCodeStart":7779,"sourceCodeEnd":7815,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-devtools-shared/src/backend/fiber/renderer.js#L7779-L7815","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// when embedding devtools-shared: counter map diverged from pseudo keys - reset session\ntry {\n  renderer.handleCommitFiberRoot(root, priorityLevel);\n} catch (err) {\n  if (err.message.includes('Expected counter to be known')) {\n    location.reload(); // counters are session-local and rebuilt on fresh attach\n  } else {\n    throw err;\n  }\n}","preventionTips":["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."],"tags":["react-devtools","fiber-root","internal-invariant","bookkeeping","display-name"],"backgroundTag":"devtools-internal-invariant","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}