{"record":{"id":"5ac43900bbbad80d","repo":"liriliri/eruda","slug":"tool-name-doesn-t-exist","errorCode":null,"errorMessage":"Tool ${name} doesn't exist","messagePattern":"Tool (.+?) doesn't exist","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/DevTools/DevTools.js","lineNumber":137,"sourceCode":"\n    if (name === 'settings') {\n      tab.append({\n        id: name,\n        title: name,\n      })\n    } else {\n      tab.insert(tab.length - 1, {\n        id: name,\n        title: name,\n      })\n    }\n\n    return this\n  }\n  remove(name) {\n    const tools = this._tools\n\n    if (!tools[name]) return logger.warn(`Tool ${name} doesn't exist`)\n\n    this._tab.remove(name)\n\n    const tool = tools[name]\n    delete tools[name]\n    if (tool.active) {\n      const toolKeys = keys(tools)\n      if (toolKeys.length > 0) this.showTool(tools[last(toolKeys)].name)\n    }\n    tool.destroy()\n\n    return this\n  }\n  removeAll() {\n    each(this._tools, (tool) => this.remove(tool.name))\n\n    return this\n  }","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/liriliri/eruda/blob/0c55928fec802fb2102934c4b5928686178b467b/src/DevTools/DevTools.js#L119-L155","documentation":"devtools.remove(name) unregisters the tool registered under `name`: it removes the tab, deletes it from the internal tools map, and calls the tool's destroy(). If no tool with that name exists in `this._tools`, the library logs this warning and does nothing. removeAll() also funnels through remove(), so it emits this for any entry already gone.","triggerScenarios":"Calling devtools.remove(name) (or eruda.remove(name)) with a name that was never added, a name that was already removed, a misspelled tool name, or removing a tool before add() completed; also when removeAll() races with a prior remove of the same tool.","commonSituations":"Teardown/cleanup code that runs twice (HMR, StrictMode double-invocation, repeated page init); typos in tool names ('console' vs 'Console'); removing a built-in tool by a name that doesn't match its registered key; calling remove() on a fresh DevTools instance that never had the tool added.","solutions":["Check that the tool exists first: only call remove(name) when devtools.get(name) is truthy.","Verify the exact registered name (tool.name as passed to add()); names are case-sensitive.","Make cleanup idempotent so repeated remove() calls for an already-removed tool are skipped.","If removeAll() is used, ensure no other code concurrently removes individual tools."],"exampleFix":"// before\neruda.remove('console')\n\n// after\nif (eruda.get('console')) {\n  eruda.remove('console')\n}","handlingStrategy":"validation","validationCode":"if (devtools.get(name)) {\n  devtools.remove(name)\n}","typeGuard":"function canRemove(devtools, name) {\n  return typeof name === 'string' && !!devtools.get(name);\n}","tryCatchPattern":null,"preventionTips":["Check get(name) before calling remove(name).","Use the exact tool.name string used at add() time; names are case-sensitive.","Write idempotent teardown so calling remove() twice is harmless.","Avoid manual remove loops — prefer removeAll() when clearing everything."],"tags":["devtools","missing-tool","cleanup","warning"],"backgroundTag":"tool-not-registered","analyzedSha":"0c55928fec802fb2102934c4b5928686178b467b","analyzedAt":"2026-09-01T18:07:51.703Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}