neoclide/coc.nvim · error

extension ${id} not found

Error message

extension ${id} not found

What it means

watchExtension(id) in src/extension/manager.ts looks the extension up via getExtension and throws `extension <id> not found` if there is no such registered extension. Watching is only possible for extensions currently known to the manager (single-file ones use a file watcher; folder ones use a watchman client).

Source

Thrown at src/extension/manager.ts:627

    } else {
      this.states.setDisable(id, false)
      if (id.startsWith('single-')) {
        let filepath = path.join(this.singleExtensionsRoot, `${id.replace(/^single-/, '')}.js`)
        await this.loadExtensionFile(filepath)
      } else {
        let folder = this.states.getFolder(id)
        if (folder) {
          await this.loadExtension(folder)
        } else {
          void window.showWarningMessage(`Extension ${id} not found`)
        }
      }
    }
  }

  public async watchExtension(id: string): Promise<void> {
    let item = this.getExtension(id)
    if (!item) throw new Error(`extension ${id} not found`)
    if (id.startsWith('single-')) {
      void window.showInformationMessage(`watching ${item.filepath}`)
      this.disposables.push(watchFile(item.filepath, async () => {
        await this.loadExtensionFile(item.filepath)
        void window.showInformationMessage(`reloaded ${id}`)
      }, global.__TEST__ === true))
    } else {
      let client = await workspace.fileSystemWatchers.createClient(item.directory, true)
      if (!client) throw new Error('watchman not found')
      void window.showInformationMessage(`watching ${item.directory}`)
      client.subscribe('**/*.js', async () => {
        this.reloadExtension(id).then(() => {
          void window.showInformationMessage(`reloaded ${id}`)
        }, onUnexpectedError)
      })
    }
  }

View on GitHub (pinned to 50e974d969)

Solutions

  1. Load the extension first, then call watchExtension with the same id
  2. Verify the id matches the registered extension (getExtension(id) returns an item)
  3. Fix typos in the id passed to the watch command/configuration
  4. Re-check that the extension wasn't disabled or unloaded before watching

Example fix

// before
await manager.watchExtension('coc-mydevext') // not loaded yet
// after
await manager.loadExtension('~/.vim/dev/coc-mydevext')
await manager.watchExtension('coc-mydevext')
Defensive patterns

Strategy: validation

Validate before calling

if (!manager.getExtension(id)) {
  logger.warn(`cannot watch ${id}: not loaded`)
  return
}

Try / catch

try {
  await manager.watchExtension(id)
} catch (e) {
  if (/not found$/.test(e.message)) logger.warn(`watch skipped: ${id} missing`)
  else throw e
}

Prevention

When it happens

Trigger: Calling watchExtension with an id never loaded, already unloaded, or misspelled; invoking it from a command after the extension was removed from the registry.

Common situations: Development-time watch setup for an extension whose load failed earlier; stale id after an extension rename; watch command run before the extension is loaded in a fresh session.

Related errors


AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31). Data as JSON: /api/errors/7eb717e3bff2338d. Report an issue: GitHub.