Summary
After phpantom_lsp 0.10.0 auto-downloaded, PHPantom fails to start additional language clients in a multi-root workspace with:
Error: command 'phpantom.navigateToPrototype' already exists
Failed to restart PHPantom language server: command 'phpantom.navigateToPrototype' already exists
The first workspace folder's client starts. Later folders never get a working server.
Environment
- Editor: Cursor
- Extension:
phpantom.phpantom 0.6.0 (latest on Open VSX)
- Language server: 0.10.0 (auto-downloaded via
phpantom.autoUpdate; GitHub release published 2026-08-20T01:22:23Z)
- OS: macOS darwin-arm64
- Workspace: 4-root workspace (four folders, one window)
Steps to reproduce
- Open a multi-root workspace (two or more folders).
- Use extension 0.6.0 with
phpantom.releaseTag = "latest" / phpantom.autoUpdate = true.
- Let (or trigger) download of
phpantom_lsp 0.10.0.
- Open PHP files in more than one folder, or run PHPantom: Restart Server.
Expected
Each workspace folder gets its own language client (as of 0.5.0). Commands advertised by the server should not collide across clients.
Actual
Client 2+ fail during LanguageClient.doInitialize → ExecuteCommandFeature.register. Output channel:
[Error] Server initialization failed.
Error: command 'phpantom.navigateToPrototype' already exists
at ExecuteCommandFeature.register (.../phpantom.phpantom-0.6.0-universal/dist/extension.js)
at LanguageClient2.initializeFeatures
at LanguageClient2.doInitialize
at LanguageClient2.start
at startClient
at startFolderClient
at ensureClientForDocument
at startClientsForOpenDocuments
PHPantom client: couldn't create connection to server.
Sending document notification textDocument/didOpen failed
Failed to restart PHPantom language server: command 'phpantom.navigateToPrototype' already exists
Why this started with 0.10.0
phpantom.navigateToPrototype is not contributed in the extension package.json. It is advertised by the 0.10.0 language server as an LSP workspace/executeCommand command (the string is present in the 0.10.0 phpantom_lsp binary).
Extension 0.6.0 starts one LanguageClient per workspace folder (startFolderClient / ensureClientForDocument). vscode-languageclient's ExecuteCommandFeature.register calls vscode.commands.registerCommand for every command the server advertises. Those registrations are global to the extension host, so the second folder client throws already exists and aborts initialization.
0.9.0 did not advertise this command, so multi-root worked. Any new server-advertised command will hit the same bug.
Workaround
Pin the language server until the extension dedupes command registration:
{
"phpantom.releaseTag": "0.9.0",
"phpantom.autoUpdate": false
}
Then PHPantom: Restart Server (or reload the window). Alternatively, open each repo in a single-root window.
Suggested fix
Register server-advertised execute commands once for the whole extension (first client wins, or a shared dispatcher that routes to the owning folder client), instead of per-folder registerCommand. Prefixing by folder would also work but would break a stable command id.
The collision is in the extension; 0.10.0 advertising a new command is expected LSP behavior.
Summary
After
phpantom_lsp0.10.0 auto-downloaded, PHPantom fails to start additional language clients in a multi-root workspace with:The first workspace folder's client starts. Later folders never get a working server.
Environment
phpantom.phpantom0.6.0 (latest on Open VSX)phpantom.autoUpdate; GitHub release published 2026-08-20T01:22:23Z)Steps to reproduce
phpantom.releaseTag="latest"/phpantom.autoUpdate=true.phpantom_lsp0.10.0.Expected
Each workspace folder gets its own language client (as of 0.5.0). Commands advertised by the server should not collide across clients.
Actual
Client 2+ fail during
LanguageClient.doInitialize→ExecuteCommandFeature.register. Output channel:Why this started with 0.10.0
phpantom.navigateToPrototypeis not contributed in the extensionpackage.json. It is advertised by the 0.10.0 language server as an LSPworkspace/executeCommandcommand (the string is present in the 0.10.0phpantom_lspbinary).Extension 0.6.0 starts one
LanguageClientper workspace folder (startFolderClient/ensureClientForDocument).vscode-languageclient'sExecuteCommandFeature.registercallsvscode.commands.registerCommandfor every command the server advertises. Those registrations are global to the extension host, so the second folder client throwsalready existsand aborts initialization.0.9.0 did not advertise this command, so multi-root worked. Any new server-advertised command will hit the same bug.
Workaround
Pin the language server until the extension dedupes command registration:
{ "phpantom.releaseTag": "0.9.0", "phpantom.autoUpdate": false }Then PHPantom: Restart Server (or reload the window). Alternatively, open each repo in a single-root window.
Suggested fix
Register server-advertised execute commands once for the whole extension (first client wins, or a shared dispatcher that routes to the owning folder client), instead of per-folder
registerCommand. Prefixing by folder would also work but would break a stable command id.The collision is in the extension; 0.10.0 advertising a new command is expected LSP behavior.