Skip to main content
Docs / TROUBLESHOOTING

F.A.Q & Common Issues

Current answers for completion, keymaps, diagnostics, runtime failures, logs, and floating UI problems.

Last verified: 2026-08-23

These answers explain concepts and stable configuration choices. They are not an incident checklist: for an executable symptom-by-symptom diagnosis, use the Troubleshooting Center.

Completion and keymaps

Tab completion and pairs

Put mappings in your own Vim configuration. Do not edit files under the coc.nvim/plugin/ directory: plugin updates replace them.

This example keeps the current completion priorities, optionally expands or jumps snippets, skips a closing pair, and otherwise starts completion:

vim snippet
1function! CheckBackspace() abort
2 let col = col('.') - 1
3 return !col || getline('.')[col - 1] =~# '\s'
4endfunction
5 
6function! NextCharIsPair() abort
7 return index([')', ']', '}', '>', "'", '"', '`'], getline('.')[col('.') - 1]) >= 0
8endfunction
9 
10inoremap <silent><expr> <Tab>
11 \ coc#pum#visible() ? coc#pum#select_confirm() :
12 \ coc#inline#visible() ? coc#inline#accept() :
13 \ coc#expandableOrJumpable() ?
14 \ "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
15 \ NextCharIsPair() ? "\<Right>" :
16 \ CheckBackspace() ? "\<Tab>" :
17 \ coc#refresh()
18 
19let g:coc_snippet_next = '<Tab>'

The snippet branch requires coc-snippets; remove that branch and g:coc_snippet_next when snippets are not installed. See Completion for the maintained mapping examples.

Tab or Enter conflicts

Only one final mapping can own a key in each mode. Inspect the active mapping and the script that last defined it:

vim snippet
1:verbose imap <Tab>
2:verbose imap <CR>

Configure the competing plugin through its documented public mapping API, then create one mapping with the priority you want. Avoid checks for another plugin’s private buffer variables because those are not stable interfaces.

Completion does not start

Check the buffer and the registered sources before changing timing settings:

  1. Run :CocCommand document.checkBuffer to verify that coc.nvim attached to the buffer.
  2. Run :CocList sources to inspect enabled sources and their filetypes.
  3. Confirm that the required extension or custom language server is running. coc.nvim does not bundle language servers.
  4. Check suggest.autoTrigger; use coc#refresh() to test manual completion.

suggest.triggerCompletionWait adds a delay between a text change and completion start. Its default is 0; increasing it does not make a language server process changes faster.

Buffer words are missing

The buffer source indexes other coc-attached normal buffers. A missing buffer should normally be loaded and have an empty buftype. Run :CocCommand document.checkBuffer in that buffer and use :CocList sources to confirm that the buffer source is enabled.

Omnifunc completion

coc.nvim does not expose an omnifunc adapter. Vim omnifunc is synchronous, while completion providers may stream incomplete results and react to trigger characters. For manual-only completion, set suggest.autoTrigger to none and map coc#refresh():

vim snippet
1if has('nvim')
2 inoremap <silent><expr> <C-Space> coc#refresh()
3else
4 inoremap <silent><expr> <C-@> coc#refresh()
5endif

Diagnostics and highlights

Diagnostics in insert mode

Diagnostics are not refreshed in insert mode by default. This is a UI refresh policy, not evidence that the linter is slow. Set diagnostic.refreshOnInsertMode to true only when you want diagnostic highlights, signs, and messages updated while typing; it can add extra UI work.

Diagnostic signs are missing

Use set signcolumn=yes to keep a stable sign column. If another plugin places a higher-priority sign on the same line, adjust diagnostic.signPriority; the coc.nvim default is 10. Avoid an unnecessarily extreme value because sign priority is shared with other plugins.

Easymotion diagnostics

If temporary easymotion text is interpreted as a document change, disable diagnostics for the buffer during the prompt:

vim snippet
1autocmd User EasyMotionPromptBegin let b:coc_diagnostic_disable = 1
2autocmd User EasyMotionPromptEnd let b:coc_diagnostic_disable = 0

b:coc_diagnostic_disable is the public buffer variable for this purpose.

Colorscheme overrides

Colorschemes commonly clear highlight definitions. Reapply custom coc.nvim highlights from a ColorScheme autocommand:

vim snippet
1augroup coc_colors
2 autocmd!
3 autocmd ColorScheme * highlight CocSearch ctermfg=12 guifg=#18A3FF
4augroup END

Completion selection color

CocMenuSel highlights the selected completion item. Define it after the colorscheme when the inherited PmenuSel colors do not work with nested highlights:

vim snippet
1autocmd ColorScheme * highlight CocMenuSel ctermbg=237 guibg=#13354A

Runtime and language servers

Node.js requirement

coc.nvim requires Node.js >= 22.15.0 at runtime. Check the executable used by your shell with node --version; :CocInfo reports the version used by the running service. To select another executable, set the path before coc.nvim starts:

vim snippet
1let g:coc_node_path = '/absolute/path/to/node'

Unsaved buffers

Support for an unnamed buffer is language-server specific. Many servers require a file URI, a recognized extension, or a workspace folder before they start. Save the buffer to a real path, verify it with :CocCommand document.checkBuffer, and inspect :CocInfo. Restart only when that server or extension requires it; :CocRestart restarts the whole coc.nvim service and is not the first troubleshooting step.

Editor freezes

CocAction() and CocRequest() are synchronous and block the editor until their request finishes. Prefer CocActionAsync() and CocRequestAsync() for mappings and ordinary autocommands. Formatting from BufWritePre is the important exception: use synchronous CocAction('format') so the write waits for the edit.

Profile Vim or Neovim

vim snippet
1:profile start profile.log
2:profile func *
3:profile file *

Reproduce the issue, run :profile stop, and inspect profile.log. Current Vim 9 and Neovim both support stopping a profile without exiting.

Collect coc.nvim logs

Set the log level before coc.nvim starts, reproduce the problem, and open the service log:

vim snippet
1let $NVIM_COC_LOG_LEVEL = 'trace'
2:CocOpenLog

For low-level communication between Vim/Neovim and the Node.js client, set g:node_client_debug = 1, restart the editor, and use coc#client#open_log(). The path is also available in $NODE_CLIENT_LOG_FILE. Remove trace logging after diagnosis because it is verbose.

Floating UI

Show hover documentation

Map the asynchronous hover action:

vim snippet
1nnoremap <silent> K <Cmd>call CocActionAsync('doHover')<CR>

Float after scrolling

Do not treat a stale or incorrectly positioned coc.nvim float as expected behavior. Update coc.nvim and the editor, reproduce with a minimal configuration, then collect :CocInfo and :CocOpenLog output for a bug report. coc#float#close_all() can clear stale coc.nvim floats while diagnosing the cause.

Disable floating windows

Use the target setting for each feature instead of a global switch:

  • suggest.enableFloat: false disables completion documentation floats.
  • diagnostic.messageTarget: "echo" sends diagnostic messages to the command line.
  • signature.target: "echo" sends signature help to the command line.
  • hover.target: "echo" uses the command line; "preview" uses the preview window.

Search these keys in the Settings Generator to inspect their current scopes and defaults.

Floating window colors

CocFloating controls the main floating-window background. A colorscheme that links it to a reversed group can be overridden after the colorscheme loads:

vim snippet
1autocmd ColorScheme * highlight link CocFloating Normal

Scroll floating windows

Use coc#float#has_scroll() to preserve the normal meaning of a key when no coc.nvim float can scroll:

vim snippet
1nnoremap <silent><nowait><expr> <C-f> coc#float#has_scroll() ? coc#float#scroll(1) : "\<C-f>"
2nnoremap <silent><nowait><expr> <C-b> coc#float#has_scroll() ? coc#float#scroll(0) : "\<C-b>"

Use coc#pum#scroll() for the completion popup menu instead.

Use <Plug>(coc-openlink) or CocActionAsync('openLink') for a link under the cursor. On Neovim, <Plug>(coc-float-jump) can focus the first focusable float; Vim popups cannot normally receive focus.

Cursor after CocList

If a terminal fails to restore the cursor shape after CocList closes, disable coc.nvim’s transparent-cursor workaround before startup:

vim snippet
1let g:coc_disable_transparent_cursor = 1