vuejs/devtools-v6 · warning

Inspector ${inspectorId} not found

Error message

Inspector ${inspectorId} not found

What it means

The devtools frontend keeps a list of registered custom inspectors. When a TO_FRONT_CUSTOM_INSPECTOR_TREE bridge message arrives from the backend, it looks up the inspector by id AND appId; if none matches, it warns and drops the tree payload. This means the backend sent tree data for an inspector the frontend never registered (or already removed, e.g. after an app switch).

Source

Thrown at packages/app-frontend/src/features/inspector/custom/composable.ts:183

  selectedIdsStorage = getStorage(SELECTED_NODES_STORAGE, {})

  bridge.on(BridgeEvents.TO_FRONT_CUSTOM_INSPECTOR_LIST, ({ inspectors: list }) => {
    list.forEach((inspector) => {
      if (!inspectors.value.some(i => i.id === inspector.id && i.appId === inspector.appId)) {
        inspectors.value.push(inspectorFactory(inspector))
      }
    })
  })

  bridge.on(BridgeEvents.TO_FRONT_CUSTOM_INSPECTOR_ADD, () => {
    fetchInspectors()
  })

  bridge.on(BridgeEvents.TO_FRONT_CUSTOM_INSPECTOR_TREE, ({ appId, inspectorId, rootNodes }) => {
    const inspector = inspectors.value.find(i => i.id === inspectorId && i.appId === appId)

    if (!inspector) {
      console.warn(`Inspector ${inspectorId} not found`)
      return
    }

    inspector.rootNodes = rootNodes
  })

  bridge.on(BridgeEvents.TO_FRONT_CUSTOM_INSPECTOR_STATE, ({ appId, inspectorId, state }) => {
    const inspector = inspectors.value.find(i => i.id === inspectorId && i.appId === appId)

    if (!inspector) {
      console.warn(`Inspector ${inspectorId} not found`)
      return
    }

    inspector.state = parse(state)
  })

  bridge.on(BridgeEvents.TO_FRONT_CUSTOM_INSPECTOR_SELECT_NODE, ({ appId, inspectorId, nodeId }) => {

View on GitHub (pinned to dd2ab5d427)

Solutions

  1. Ensure addCustomInspector is called (and its TO_FRONT registration acknowledged) on the frontend before the backend emits tree events with that id.
  2. Verify the appId passed by the backend matches the app the inspector was registered under.
  3. Re-register inspectors after app reconnect/hot-reload before emitting new tree data.
  4. Log the incoming appId/inspectorId vs the registered list to find the mismatch.

Example fix

// before
bridge.emit(BridgeEvents.TO_FRONT_CUSTOM_INSPECTOR_TREE, { inspectorId, rootNodes }) // appId missing

// after
bridge.emit(BridgeEvents.TO_FRONT_CUSTOM_INSPECTOR_TREE, { appId: appRecord.id, inspectorId, rootNodes })
Defensive patterns

Strategy: try-catch

Validate before calling

const inspector = inspectors.value.find(i => i.id === inspectorId && i.appId === appId)
if (!inspector) return // skip emit or re-register first

Type guard

function inspectorExists(list, id, appId) { return list.some(i => i.id === id && i.appId === appId) }

Try / catch

bridge.on(BridgeEvents.TO_FRONT_CUSTOM_INSPECTOR_TREE, (payload) => {
  if (!inspectorExists(inspectors.value, payload.inspectorId, payload.appId)) {
    console.warn('Ignoring tree for unregistered inspector', payload.inspectorId)
    return
  }
  // apply tree
})

Prevention

When it happens

Trigger: Backend emits TO_FRONT_CUSTOM_INSPECTOR_TREE with an inspectorId that has no matching entry in `inspectors.value` with the same `appId` — unregistered inspector, stale id after reconnect, or appId mismatch when multiple apps are connected.

Common situations: Custom inspector registered on a different app than the one emitting the tree; hot-reload clearing frontend inspector state while the backend still pushes updates; backend plugin registration raced ahead of frontend registration.

Related errors


AI-assisted analysis of vuejs/devtools-v6@dd2ab5d427 (2026-08-31). Data as JSON: /api/errors/ef9ebc68d5d97219. Report an issue: GitHub.