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
- Load the extension first, then call watchExtension with the same id
- Verify the id matches the registered extension (getExtension(id) returns an item)
- Fix typos in the id passed to the watch command/configuration
- 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
- Establish a load-then-watch ordering in dev tooling
- Use consistent ids between load and watch calls
- Cancel pending watch requests when extensions unload
- Check watcher setup only for extensions that loaded successfully
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
- Command: ${command} not found
- ${this.def} has no release older than ${releaseAge} days.
- ${this.def} is not older than ${releaseAge} days.
- Extension ${id} not registered!
- extension ${id} not registered
AI-assisted analysis of neoclide/coc.nvim@50e974d969 (2026-08-31).
Data as JSON: /api/errors/7eb717e3bff2338d.
Report an issue: GitHub.