[Biome] Process remains after closing vim
When opening a file ...ts and having Biome set up and closing vim, there remains a running process.
/usr/bin/biome __run_server --stop-on-discronnect --log-path=/home/user/.cache/biome/biome-logs --log-prefix=server.log
Reproduction
vim a.ts
:qa # or even :q
btop # enter: f biome
System
Biome is installed system-wide. OS: Arch Linux ALE version: https://github.com/dense-analysis/ale/commit/b9d7f56471084e7ac8070c90315170ef703217ff Vim version: 9.1.1841
VIM - Vi IMproved 9.1 (2024 Jan 02 kompiliert am Oct 09 2025 19:38:56)
Inklusive der Patches: 1-1841
vimrc
" Basic (priority)
set t_Co=256
"" Needed for 'set termguicolors'
let &t_8b = "\<Esc>[48:2:%lu:%lu:%lum"
let &t_8f = "\<Esc>[38:2:%lu:%lu:%lum"
" Plugins (priority)
"" vim-airline
let g:airline_powerline_fonts = 1
let g:airline_theme = 'molokai'
""" Symbols (See: https://github.com/vim-airline/vim-airline/issues/2706)
if !exists('g:airline_symbols')
let g:airline_symbols = {}
endif
let g:airline_left_sep = '»'
let g:airline_left_sep = '▶'
let g:airline_right_sep = '«'
let g:airline_right_sep = '◀'
let g:airline_symbols.colnr = ' ㏇:'
let g:airline_symbols.colnr = ' ℅:'
let g:airline_symbols.crypt = '🔒'
let g:airline_symbols.linenr = '☰'
let g:airline_symbols.linenr = ' ␊:'
let g:airline_symbols.linenr = ' :'
let g:airline_symbols.linenr = '¶'
let g:airline_symbols.maxlinenr = ''
let g:airline_symbols.maxlinenr = '㏑'
let g:airline_symbols.branch = '⎇'
let g:airline_symbols.paste = 'ρ'
let g:airline_symbols.paste = 'Þ'
let g:airline_symbols.paste = '∥'
let g:airline_symbols.spell = 'Ꞩ'
let g:airline_symbols.notexists = 'Ɇ'
let g:airline_symbols.whitespace = 'Ξ'
"" vim-ale
let g:ale_fix_on_save = 1
let g:ale_fixers =
\{
\ '*': ['remove_trailing_lines', 'trim_whitespace'],
\ 'bib': ['bibclean', 'remove_trailing_lines', 'trim_whitespace'],
\ 'cpp': ['clang-format', 'remove_trailing_lines', 'trim_whitespace'],
\ 'cmake': ['cmakeformat', 'remove_trailing_lines', 'trim_whitespace'],
\ 'css': ['css-beautify', 'remove_trailing_lines', 'stylelint', 'trim_whitespace'],
\ 'desktop': ['remove_trailing_lines', 'trim_whitespace'],
\ 'html': ['remove_trailing_lines', 'tidy', 'trim_whitespace'],
\ 'java': ['clang-format', 'remove_trailing_lines', 'trim_whitespace'],
\ 'json': ['dprint', 'remove_trailing_lines', 'trim_whitespace'],
\ 'mail': ['remove_trailing_lines', 'trim_whitespace'],
\ 'make': ['remove_trailing_lines', 'trim_whitespace'],
\ 'markdown': ['dprint', 'remove_trailing_lines', 'trim_whitespace'],
\ 'PKGBUILD': ['remove_trailing_lines', 'shfmt', 'trim_whitespace'],
\ 'po': ['remove_trailing_lines', 'trim_whitespace'],
\ 'python': ['autoflake', 'autopep8', 'isort', 'remove_trailing_lines', 'ruff', 'trim_whitespace', 'yapf'],
\ 'sh': ['remove_trailing_lines', 'shfmt', 'trim_whitespace'],
\ 'systemd': ['remove_trailing_lines', 'trim_whitespace'],
\ 'tex': ['latexindent', 'remove_trailing_lines', 'trim_whitespace'],
\ 'text': ['remove_trailing_lines', 'trim_whitespace'],
\ 'toml': ['dprint', 'remove_trailing_lines', 'trim_whitespace'],
\ 'typescript': ['dprint', 'remove_trailing_lines', 'trim_whitespace'],
\ 'vim': ['remove_trailing_lines', 'trim_whitespace'],
\ 'xml': ['remove_trailing_lines', 'trim_whitespace', 'xmllint'],
\ 'yaml': ['remove_trailing_lines', 'trim_whitespace', 'yamlfmt'],
\ 'zsh': ['remove_trailing_lines', 'shfmt', 'trim_whitespace']
\}
let g:ale_linter_aliases =
\{
\ 'PKGBUILD': 'sh',
\ 'zsh': 'sh'
\}
""" Language servers are handled by YouCompleteMe and thus not included here.
let g:ale_linters =
\{
\ 'bib': ['bibclean'],
\ 'cpp': ['clangtidy'],
\ 'cmake': ['cmake_lint'],
\ 'css': ['stylelint'],
\ 'desktop': ['desktop_file_validate'],
\ 'gitcommit': ['gitlint'],
\ 'html': ['htmlhint', 'tidy'],
\ 'java': ['javac', 'pmd'],
\ 'json': ['jq'],
\ 'mail': [],
\ 'make': ['checkmake'],
\ 'markdown': ['markdownlint'],
\ 'PKGBUILD': ['shell', 'shellcheck'],
\ 'po': ['msgfmt'],
\ 'python': ['bandit', 'mypy', 'pycodestyle', 'pydocstyle', 'pyflakes', 'pyright', 'ruff', 'vulture'],
\ 'sh': ['shell', 'shellcheck'],
\ 'systemd': ['systemd_analyze'],
\ 'tex': ['chktex'],
\ 'text': [],
\ 'toml': [],
\ 'typescript': ['biome'],
\ 'vim': ['vint'],
\ 'xml': ['xmllint'],
\ 'yaml': ['yamllint'],
\ 'zsh': ['shell', 'shellcheck']
\}
let g:ale_linters_explicit = 1
let g:ale_virtualtext_cursor = 0
""" c
let g:ale_c_clangformat_options = '--style file:' . $XDG_CONFIG_HOME . '/clang/clang-format.yaml'
""" cmake
let g:ale_cmake_cmake_lint_options = '-c=' . $XDG_CONFIG_HOME . '/cmake-lang/cmake-lang.yaml'
let g:ale_cmake_cmakeformat_options = '-c=' . $XDG_CONFIG_HOME . '/cmake-lang/cmake-lang.yaml'
""" cpp
let g:ale_cpp_clangtidy_extra_options = '--config-file=' . $XDG_CONFIG_HOME . '/clang/clang-tidy.yaml'
""" css
let g:ale_css_css_beautify_options = '--config ' . $XDG_CONFIG_HOME . '/js-beautify/css-beautify.json'
let g:ale_css_stylelint_options = '--cache --cache-location ' . $XDG_CACHE_HOME . '/stylelint/ --config ' . $XDG_CONFIG_HOME . '/stylelint/stylelintrc.yaml'
""" dprint
let g:ale_dprint_config = $XDG_CONFIG_HOME . '/dprint/dprint.json'
""" html
let g:ale_html_htmlhint_options = '-c ' . $XDG_CONFIG_HOME . '/htmlhint/htmlhintrc.yaml'
let g:ale_html_tidy_options = '-config ' . $XDG_CONFIG_HOME . '/tidy/tidyrc -q'
""" java
let g:ale_java_pmd_options = '--cache ' . $XDG_CACHE_HOME . '/pmd/cache -R ' . $XDG_CONFIG_HOME . '/pmd/rules.xml'
""" markdown
let g:ale_markdown_markdownlint_executable = 'markdownlint-cli2'
let g:ale_markdown_markdownlint_options = '--config ' . $XDG_CONFIG_HOME . '/markdownlint/.markdownlint.yaml'
""" python
let g:ale_python_mypy_options = '--strict'
let g:ale_python_pycodestyle_options = '--max-line-length 120'
let g:ale_python_pyright_config =
\{
\ 'pyright':
\ {
\ 'disableLanguageServices': v:true,
\ 'disableOrganizeImports': v:false
\ },
\ 'python':
\ {
\ 'analysis':
\ {
\ 'autoImportCompletions': v:true,
\ 'autoSearchPaths': v:true,
\ 'diagnosticMode': 'openFilesOnly',
\ 'diagnosticSeverityOverrides': {},
\ 'extraPaths': [],
\ 'logLevel': 'Information',
\ 'stubPath': '',
\ 'typeCheckingMode': 'strict',
\ 'typeshedPaths': [],
\ 'useLibraryCodeForTypes': v:true
\ },
\ 'pythonPath': 'python',
\ 'venvPath': ''
\ }
\}
let g:ale_python_vulture_options = '--min-confidence 100'
""" sh
let g:ale_sh_shellcheck_options = '-a -Calways -o all -P SCRIPTDIR -S style -x'
let g:ale_sh_shfmt_options = '-ci -fn -i 4 -sr'
""" tex
let g:ale_tex_chktex_options = '-H -I -n 36 -n 44'
let g:ale_tex_latexindent_options = '-c /tmp/latexindent/'
""" typescript
let g:ale_biome_lsp_project_root = $XDG_CONFIG_HOME . '/biome/'
""" yaml
let g:ale_yaml_yamlfmt_options = '-conf ' . $XDG_CONFIG_HOME . '/yamlfmt/yamlfmt.yaml'
let g:ale_yaml_yamllint_options = '-c ' . $XDG_CONFIG_HOME . '/yamllint/yamllint.yaml'
"" vim-code-minimap
let g:minimap_auto_start = 1
let g:minimap_git_colors = 1
let g:minimap_highlight_search = 1
let g:minimap_width = 25
"" vim-gruvbox-community
let g:gruvbox_italic = 1
"" vim-nerdtree
let g:NERDTreeShowHidden = 1
"" vim-youcompleteme
let g:ycm_enable_semantic_highlighting = 1
""" Clang, jdt.ls, Jedi and TSServer are supported natively and therefore not included here.
let g:ycm_language_server =
\[
\ {
\ 'cmdline': ['autotools-language-server'],
\ 'filetypes': ['automake', 'config', 'make'],
\ 'name': 'autotools'
\ },
\ {
\ 'cmdline': ['cmake-language-server', 'start'],
\ 'filetypes': ['cmake'],
\ 'name': 'cmake'
\ },
\ {
\ 'cmdline': ['vscode-css-language-server', '--stdio'],
\ 'filetypes': ['css'],
\ 'name': 'css'
\ },
\ {
\ 'cmdline': ['vscode-html-language-server', '--stdio'],
\ 'filetypes': ['html'],
\ 'name': 'html'
\ },
\ {
\ 'cmdline': ['java-language-server'],
\ 'filetypes': ['java'],
\ 'name': 'java'
\ },
\ {
\ 'capabilities':
\ {
\ 'textDocument':
\ {
\ 'completion':
\ {
\ 'completionItem':
\ {
\ 'snippetSupport': v:true
\ }
\ }
\ }
\ },
\ 'cmdline': ['vscode-json-language-server', '--stdio'],
\ 'filetypes': ['json'],
\ 'name': 'json'
\ },
\ {
\ 'cmdline': ['marksman', 'server'],
\ 'filetypes': ['markdown'],
\ 'name': 'markdown'
\ },
\ {
\ 'cmdline': ['mutt-language-server'],
\ 'filetypes': ['neomuttrc'],
\ 'name': 'neomuttrc'
\ },
\ {
\ 'cmdline': ['termux-language-server'],
\ 'filetypes': ['PKGBUILD'],
\ 'name': 'pkgbuild'
\ },
\ {
\ 'cmdline': ['requirements-language-server'],
\ 'filetypes': ['requirements'],
\ 'name': 'requirements'
\ },
\ {
\ 'cmdline': ['bash-language-server', 'start'],
\ 'filetypes': ['sh', 'zsh'],
\ 'name': 'shell'
\ },
\ {
\ 'cmdline': ['texlab'],
\ 'filetypes': ['tex'],
\ 'name': 'tex'
\ },
\ {
\ 'cmdline': ['tmux-language-server'],
\ 'filetypes': ['tmux'],
\ 'name': 'tmux'
\ },
\ {
\ 'cmdline': ['vim-language-server', '--stdio'],
\ 'filetypes': ['vim'],
\ 'name': 'vim'
\ },
\ {
\ 'capabilities':
\ {
\ 'textDocument':
\ {
\ 'completion':
\ {
\ 'completionItem':
\ {
\ 'snippetSupport': v:true
\ }
\ }
\ },
\ 'workspace':
\ {
\ 'configuration': v:true
\ }
\ },
\ 'cmdline': ['yaml-language-server', '--stdio'],
\ 'filetypes': ['yaml'],
\ 'name': 'yaml'
\ }
\]
"" Setup (The plugins need to be loaded at the end of the plugin configuration.)
call plug#begin($XDG_DATA_HOME . '/vim/plugged/')
Plug '/usr/share/vim/vimfiles/'
call plug#end()
" Autocommands
augroup vimrc
autocmd!
"" File types
autocmd vimrc BufNewFile,BufRead *.html set filetype=html
"" Navigation
autocmd vimrc VimEnter * NERDTree | wincmd p
autocmd vimrc BufEnter NERD_tree_* | execute 'normal R'
augroup end
" Basic
colorscheme gruvbox
filetype indent on
filetype plugin on
set autoindent
set autoread
set background=dark
set backspace=eol,indent,start
set breakindent
set cdhome
set encoding=UTF-8
scriptencoding UTF-8
set laststatus=2
set list
set listchars=tab:>-,trail:~
" vint: -ProhibitSetNoCompatible
set nocompatible
set number
set shiftwidth=4
set smartindent
set termguicolors
set ttimeoutlen=10
syntax on
" Commands
set history=100
set wildmenu
" Cursor
set cursorline
set cursorlineopt=line,number
set scrolloff=5
" Search
set hlsearch
set ignorecase
set incsearch
set showmatch
set smartcase
" Shortcuts
nnoremap <C-q> :qa<CR>
nnoremap <C-t> :NERDTreeToggle<CR>
" Spell checking
set spell
set spelllang=de_de,en_gb
" Tabs
set expandtab
set smarttab
set tabstop=4
" XDG
set runtimepath^=$XDG_CONFIG_HOME/vim/
set runtimepath+=$XDG_DATA_HOME/vim/
set runtimepath+=$XDG_CONFIG_HOME/vim/after/
set packpath^=$XDG_DATA_HOME/vim/,$XDG_CONFIG_HOME/vim/
set packpath+=$XDG_CONFIG_HOME/vim/after/,$XDG_DATA_HOME/vim/after/
let g:netrw_home = $XDG_DATA_HOME . '/vim/'
call mkdir($XDG_DATA_HOME . '/vim/spell/', 'p')
set backupdir=$XDG_STATE_HOME/vim/backup/ | call mkdir(&backupdir, 'p')
set directory=$XDG_STATE_HOME/vim/swap/ | call mkdir(&directory, 'p')
set undodir=$XDG_STATE_HOME/vim/undo/ | call mkdir(&undodir, 'p')
set viewdir=$XDG_STATE_HOME/vim/view/ | call mkdir(&viewdir, 'p')
set viminfofile=$XDG_STATE_HOME/vim/viminfo
" Highlights (Set at the end to not be overwritten.)
highlight clear ALEError
highlight ALEError cterm=underline ctermfg=red
highlight clear ALEWarning
highlight ALEWarning cterm=underline ctermfg=yellow
highlight clear SpellBad
highlight SpellBad cterm=underline
@redbmk, do you know how to solve this?
Did you intend to post this in Discussions, @Spixmaster ?
If not, what happened with the template for reporting bugs? Did it not get presented when filing the new issue?
Edit: Removed template after initial post got completed.
In addition to knowing absolute essentials like what version you're running, this issue seems pretty much unactionable without logs from biome. Can you please show the code for a hello world in javascript and confirm whether the problem happens with it or if a more complex code base is required?
I was too lazy to fill out the template. I had so much other work to do.
The issue happens all the time. Therefore, I assumed no further elaboration was needed.
I notice you've filed https://github.com/biomejs/biome/issues/7908 which is probably an issue targeting the right project.
It seems biome makes faulty assumptions rather than actually honours the information provided by the client. ALE does not announce supporting workspace/configuration, so biome really should not make any attempts calling that method.
The stale biome remains running on exiting vim, yes. Applying the patch in https://github.com/dense-analysis/ale/pull/5044 appears to make biome able to get unstuck and terminate. You might wish to look at the conversation in that pull request and chip in your code to complete it?
This was the javascript file I attempted:
function hello() {
console.log("hello javascript")
}
hello()
Resulting in these LSP messages:
{
"method": "initialize",
"jsonrpc": "2.0",
"id": 2,
"params": {
"initializationOptions": {},
"rootUri": "file:///tmp/tmp.WI82L2xEsQ",
"capabilities": {
"workspace": {
"workspaceFolders": false,
"configuration": false,
"symbol": {
"dynamicRegistration": false
},
"applyEdit": false,
"didChangeConfiguration": {
"dynamicRegistration": false
}
},
"textDocument": {
"documentSymbol": {
"dynamicRegistration": false,
"hierarchicalDocumentSymbolSupport": false
},
"references": {
"dynamicRegistration": false
},
"publishDiagnostics": {
"relatedInformation": true
},
"rename": {
"dynamicRegistration": false
},
"completion": {
"completionItem": {
"snippetSupport": false,
"commitCharactersSupport": false,
"preselectSupport": false,
"deprecatedSupport": false,
"documentationFormat": [
"plaintext",
"markdown"
]
},
"contextSupport": false,
"dynamicRegistration": false
},
"synchronization": {
"didSave": true,
"willSaveWaitUntil": false,
"willSave": false,
"dynamicRegistration": false
},
"codeAction": {
"codeActionLiteralSupport": {
"codeActionKind": {
"valueSet": []
}
},
"dynamicRegistration": false
},
"diagnostic": {
"dynamicRegistration": true,
"relatedDocumentSupport": true
},
"typeDefinition": {
"dynamicRegistration": false
},
"hover": {
"dynamicRegistration": false,
"contentFormat": [
"plaintext",
"markdown"
]
},
"implementation": {
"dynamicRegistration": false,
"linkSupport": false
},
"definition": {
"dynamicRegistration": false,
"linkSupport": false
}
}
},
"rootPath": "/tmp/tmp.WI82L2xEsQ",
"processId": 43282
}
}
{
"jsonrpc": "2.0",
"result": {
"capabilities": {
"codeActionProvider": {
"codeActionKinds": [
"quickfix.biome",
"quickfix.suppressRule.topLevel.biome",
"quickfix.suppressRule.inline.biome",
"source.organizeImports.biome",
"source.fixAll.biome",
"refactor.biome",
"refactor.extract.biome",
"refactor.inline.biome",
"refactor.rewrite.biome",
"source.biome"
]
},
"positionEncoding": "utf-16",
"textDocumentSync": 2,
"workspace": {
"workspaceFolders": {
"changeNotifications": true,
"supported": true
}
}
},
"serverInfo": {
"name": "biome_lsp",
"version": "0.0.0"
}
},
"id": 2
}
{
"method": "initialized",
"jsonrpc": "2.0",
"params": {}
}
{
"method": "textDocument/didOpen",
"jsonrpc": "2.0",
"params": {
"textDocument": {
"uri": "file:///tmp/tmp.WI82L2xEsQ/hello.js",
"version": 2,
"languageId": "javascript",
"text": "function hello() {\n console.log(\"hello javascript\")\n}\n\nhello()\n"
}
}
}
{
"jsonrpc": "2.0",
"method": "workspace/configuration",
"params": {
"items": [
{
"scopeUri": "file:///tmp/tmp.WI82L2xEsQ",
"section": "biome"
}
]
},
"id": 0
}
{
"jsonrpc": "2.0",
"method": "workspace/configuration",
"params": {
"items": [
{
"scopeUri": "file:///tmp/tmp.WI82L2xEsQ",
"section": "biome"
}
]
},
"id": 1
}
{
"id": 0,
"jsonrpc": "2.0",
"error": {
"data": "Unknown method: workspace/configuration",
"code": -32601,
"message": "Method not found"
}
}
{
"id": 1,
"jsonrpc": "2.0",
"error": {
"data": "Unknown method: workspace/configuration",
"code": -32601,
"message": "Method not found"
}
}
{
"jsonrpc": "2.0",
"method": "window/logMessage",
"params": {
"message": "Server initialized with PID: 97356",
"type": 3
}
}
{
"jsonrpc": "2.0",
"method": "client/unregisterCapability",
"params": {
"unregisterations": [
{
"id": "biome_did_change_watched_files",
"method": "workspace/didChangeWatchedFiles"
},
{
"id": "biome_formatting",
"method": "textDocument/formatting"
},
{
"id": "biome_did_change_extension_settings",
"method": "workspace/didChangeConfiguration"
},
{
"id": "biome_range_formatting",
"method": "textDocument/rangeFormatting"
},
{
"id": "biome_code_action",
"method": "textDocument/codeAction"
},
{
"id": "biome_on_type_formatting",
"method": "textDocument/onTypeFormatting"
}
]
},
"id": 2
}
{
"id": 2,
"jsonrpc": "2.0",
"error": {
"data": "Unknown method: client/unregisterCapability",
"code": -32601,
"message": "Method not found"
}
}
{
"jsonrpc": "2.0",
"method": "textDocument/publishDiagnostics",
"params": {
"diagnostics": [],
"uri": "file:///tmp/tmp.WI82L2xEsQ/hello.js",
"version": 2
}
}
{
"jsonrpc": "2.0",
"method": "client/registerCapability",
"params": {
"registrations": []
},
"id": 3
}
{
"id": 3,
"jsonrpc": "2.0",
"error": {
"data": "Unknown method: client/registerCapability",
"code": -32601,
"message": "Method not found"
}
}
{
"jsonrpc": "2.0",
"method": "textDocument/publishDiagnostics",
"params": {
"diagnostics": [],
"uri": "file:///tmp/tmp.WI82L2xEsQ/hello.js",
"version": 2
}
}
{
"method": "textDocument/didChange",
"jsonrpc": "2.0",
"params": {
"contentChanges": [
{
"text": "function hello() {\n console.log(\"hello javascript\")\n}\n\nhello()\n"
}
],
"textDocument": {
"uri": "file:///tmp/tmp.WI82L2xEsQ/hello.js",
"version": 3
}
}
}
{
"jsonrpc": "2.0",
"method": "textDocument/publishDiagnostics",
"params": {
"diagnostics": [],
"uri": "file:///tmp/tmp.WI82L2xEsQ/hello.js",
"version": 3
}
}