liriliri/eruda · warning

Tool ${name} doesn't exist

Error message

Tool ${name} doesn't exist

What it means

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.

Source

Thrown at src/DevTools/DevTools.js:137

    if (name === 'settings') {
      tab.append({
        id: name,
        title: name,
      })
    } else {
      tab.insert(tab.length - 1, {
        id: name,
        title: name,
      })
    }

    return this
  }
  remove(name) {
    const tools = this._tools

    if (!tools[name]) return logger.warn(`Tool ${name} doesn't exist`)

    this._tab.remove(name)

    const tool = tools[name]
    delete tools[name]
    if (tool.active) {
      const toolKeys = keys(tools)
      if (toolKeys.length > 0) this.showTool(tools[last(toolKeys)].name)
    }
    tool.destroy()

    return this
  }
  removeAll() {
    each(this._tools, (tool) => this.remove(tool.name))

    return this
  }

View on GitHub (pinned to 0c55928fec)

Solutions

  1. Check that the tool exists first: only call remove(name) when devtools.get(name) is truthy.
  2. Verify the exact registered name (tool.name as passed to add()); names are case-sensitive.
  3. Make cleanup idempotent so repeated remove() calls for an already-removed tool are skipped.
  4. If removeAll() is used, ensure no other code concurrently removes individual tools.

Example fix

// before
eruda.remove('console')

// after
if (eruda.get('console')) {
  eruda.remove('console')
}
Defensive patterns

Strategy: validation

Validate before calling

if (devtools.get(name)) {
  devtools.remove(name)
}

Type guard

function canRemove(devtools, name) {
  return typeof name === 'string' && !!devtools.get(name);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of liriliri/eruda@0c55928fec (2026-09-01). Data as JSON: /api/errors/5ac43900bbbad80d. Report an issue: GitHub.