neoclide/coc.nvim · error · Error

Provider returns null on prepare, unable to rename at curren

Error message

Provider returns null on prepare, unable to rename at current position

What it means

During doRefactor, the `textDocument/prepareRename` request returned `false` (or was treated as failed) at the current position, meaning the server explicitly says the symbol under the cursor cannot be renamed. coc.nvim surfaces this as the prepare-null error.

Source

Thrown at src/handler/refactor/index.ts:75

      openCommand: config.get('openCommand', 'vsplit'),
      saveToFile: config.get('saveToFile', true),
      showMenu: config.get('showMenu', '<Tab>')
    })
  }

  /**
   * Refactor of current symbol
   */
  public async doRefactor(): Promise<void> {
    let { doc, position } = await this.handler.getCurrentState()
    if (!languages.hasProvider(ProviderName.Rename, doc.textDocument)) {
      throw new Error(`Rename provider not found for current buffer`)
    }
    await doc.synchronize()
    let edit = await this.handler.withRequestToken('refactor', async token => {
      let res = await languages.prepareRename(doc.textDocument, position, token)
      if (token.isCancellationRequested) return null
      if (res === false) throw new Error(`Provider returns null on prepare, unable to rename at current position`)
      let edit = await languages.provideRenameEdits(doc.textDocument, position, 'NewName', token)
      if (token.isCancellationRequested) return null
      if (!edit) throw new Error('Provider returns null for rename edits.')
      return edit
    })
    if (edit) {
      await this.fromWorkspaceEdit(edit, doc.filetype)
    }
  }

  /**
   * Search by rg
   */
  public async search(args: string[]): Promise<void> {
    let buf = await this.createRefactorBuffer()
    let cwd = await this.nvim.call('getcwd', []) as string
    let search = new Search(this.nvim)
    await search.run(args, cwd, buf)

View on GitHub (pinned to 50e974d969)

Solutions

  1. Place the cursor directly on the symbol to rename and retry.
  2. Verify the symbol is renameable in this server (try plain `:CocRename` to compare).
  3. Wait for document diagnostics/indexing to settle (server may reject during heavy edits).
  4. Check server output for the prepareRename response details via `:CocCommand workspace.showOutput`.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await coc.commands.executeCommand('document.renameRefactor')
} catch (e) {
  if (String(e?.message).includes('Provider returns null on prepare'))
    return vim.notify('Cursor is not on a renameable symbol')
  throw e
}

Prevention

When it happens

Trigger: Cursor is on a token the server disallows renaming (keyword, comment, whitespace, generated/readonly symbol); server implements prepareRename and returns false or null for the position; request raced with document changes.

Common situations: Cursor not exactly on an identifier (e.g. on a brace or inside a string); renaming imported/readonly module paths the server marks immutable; stale cursor position after buffer edits.

Related errors


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