neoclide/coc.nvim · error

watchman not found

Error message

watchman not found

What it means

For non-single-file extensions, watchExtension relies on workspace.fileSystemWatchers.createClient(directory, true), which returns null when no watchman client can be established (watchman binary missing or service unreachable). The manager then throws `watchman not found` because folder watching cannot proceed without it.

Source

Thrown at src/extension/manager.ts:636

        } 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)
      })
    }
  }

  /**
   * load extension in folder or file
   */
  public async load(filepath: string, active: boolean, options?: ExtensionLoadOptions): Promise<ExportExtension> {
    let name: string
    if (options?.sourceCode) {
      let extensionRoot = options.extensionRoot ?? filepath
      let obj = loadJson(path.join(extensionRoot, 'package.json')) as any
      name = obj.name

View on GitHub (pinned to 50e974d969)

Solutions

  1. Install watchman (e.g. `brew install watchman` or your package manager) and ensure `watchman --version` works in the shell coc runs in
  2. Start/repair the watchman service: run `watchman watch <directory>` and check `watchman get-sockname` for errors
  3. If watchman cannot be used, fall back to reloading the extension manually instead of watchExtension
  4. Check the directory is on a local filesystem watchman supports (not NFS/network mounts)

Example fix

// before: watchman missing
await manager.watchExtension('coc-myext') // throws 'watchman not found'
// after (shell)
brew install watchman  # or apt install watchman
watchman watch ~/project  # verify service works
// then retry watchExtension
Defensive patterns

Strategy: fallback

Validate before calling

import { execFileSync } from 'child_process'
function watchmanAvailable(): boolean {
  try { execFileSync('watchman', ['--version'], { stdio: 'ignore' }); return true }
  catch { return false }
}

Try / catch

try {
  await manager.watchExtension(id)
} catch (e) {
  if (e.message === 'watchman not found') {
    logger.warn('watchman unavailable; manual reload required')
  } else throw e
}

Prevention

When it happens

Trigger: watchExtension(id) on a folder extension when watchman is not installed on PATH, the watchman service fails to start, or the watcher client cannot be created (e.g. permission or socket issues in the watched directory).

Common situations: Fresh machine without watchman installed; watchman installed but its state dir corrupted or server not running; WSL/container images lacking watchman; directory on a filesystem watchman cannot watch (network mounts).

Related errors


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