Skip to content

powernap advertises workspace/workspaceFolders but lacks handler; router panics on nil params #610

@csacca

Description

@csacca

Description

Describe the bug

  • powernap advertises capabilities.workspace.workspaceFolders: true during initialize but didn’t register a handler for workspace/workspaceFolders (server-initiated request). Servers like MATLAB-language-server call this method immediately and get no handler for method: workspace/workspaceFolders.
  • Separately, Router.Route dereferenced *req.Params without a nil check, so a server request/notification with no params could panic the client.

To Reproduce

  1. Run Crush v0.13.6 (which uses x/powernap at 25f979b) against MATLAB-language-server.
  2. After initialize/initialized, the server calls workspace/workspaceFolders with no params.
  3. Error from missing handler; or panic in Router when Params is nil.

Expected behavior

  • If the client (powernap) advertises workspaceFolders, it must respond with configured folders (or empty array).
  • Router should accept nil Params safely for both requests and notifications.

Actual behavior

  • Server calls workspace/workspaceFolders; client returns error: "no handler for method: workspace/workspaceFolders".
  • If a handler for workspace/workspaceFolders is added, client panics in Router when req.Params is nil.

Setup

  • Crush v0.13.6
    • powernap v0.0.0-20251015113943-25f979b54ad4
  • LSP Server: MATLAB-language-server v1.3.6
  • Ubuntu 24.04.3 LTS as devcontainer (mcr.microsoft.com/devcontainers/base:ubuntu-24.04)

Source Code

  • Affected code:
    • pkg/lsp/client.go — advertises workspaceFolders: true; no handler registered for workspace/workspaceFolders.
    • pkg/transport/router.go — Router.Route dereferences *req.Params without a nil check.

Additional context

  • Impacts servers that call workspace/workspaceFolders early in startup (e.g., MATLAB-language-server).
Example traffic between `crush` and `matlab-language-server`

Example traffic between crush and matlab-language-server

stdin:

Content-Length: 2837

{"id":0,"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"general":{"markdown":{"parser":"marked","version":"1.1.0"},"positionEncodings":["utf-16"],"regularExpressions":{"engine":"ECMAScript","version":"ES2020"}},"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"dataSupport":true,"dynamicRegistration":true,"isPreferredSupport":true,"resolveSupport":{"properties":["edit"]}},"completion":{"completionItem":{"commitCharactersSupport":true,"deprecatedSupport":true,"documentationFormat":["markdown","plaintext"],"insertReplaceSupport":true,"preselectSupport":true,"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"snippetSupport":false,"tagSupport":{"valueSet":[1]}},"contextSupport":true,"dynamicRegistration":true},"definition":{"dynamicRegistration":true,"linkSupport":true},"documentHighlight":{"dynamicRegistration":true},"documentSymbol":{"dynamicRegistration":true,"hierarchicalDocumentSymbolSupport":true},"formatting":{"dynamicRegistration":true},"hover":{"contentFormat":["markdown","plaintext"],"dynamicRegistration":true},"publishDiagnostics":{"codeDescriptionSupport":true,"dataSupport":true,"relatedInformation":true,"tagSupport":{"valueSet":[1,2]},"versionSupport":true},"rangeFormatting":{"dynamicRegistration":true},"references":{"dynamicRegistration":true},"rename":{"dynamicRegistration":true,"prepareSupport":true},"synchronization":{"didSave":true,"dynamicRegistration":true,"willSave":true,"willSaveWaitUntil":true}},"window":{"showDocument":{"support":true},"showMessage":{"messageActionItem":{"additionalPropertiesSupport":true}},"workDoneProgress":true},"workspace":{"applyEdit":true,"configuration":true,"didChangeConfiguration":{"dynamicRegistration":true},"didChangeWatchedFiles":{"dynamicRegistration":true,"relativePatternSupport":true},"fileOperations":{"didCreate":true,"didDelete":true,"didRename":true,"dynamicRegistration":true,"willCreate":true,"willDelete":true,"willRename":true},"symbol":{"dynamicRegistration":true},"workspaceEdit":{"documentChanges":true,"failureHandling":"textOnlyTransactional","normalizesLineEndings":true,"resourceOperations":["create","rename","delete"]},"workspaceFolders":true}},"clientInfo":{"name":"powernap","version":"0.1.0"},"initializationOptions":{"MATLAB":{"indexWorkspace":true,"installPath":"/opt/matlab/R2025b","matlabConnectionTiming":"onStart","prewarmGraphics":false,"signIn":true,"telemetry":false}},"locale":"en-us","processId":26471,"rootPath":"/workspaces/agentic-matlab-example","rootUri":"file:///workspaces/agentic-matlab-example","trace":"off","workspaceFolders":[{"uri":"file:///workspaces/agentic-matlab-example","name":"agentic-matlab-example"}]}}Content-Length: 52

{"jsonrpc":"2.0","method":"initialized","params":{}}Content-Length: 38

{"id":0,"result":null,"jsonrpc":"2.0"}Content-Length: 38

{"id":1,"result":[{}],"jsonrpc":"2.0"}Content-Length: 38

{"id":2,"result":null,"jsonrpc":"2.0"}Content-Length: 105

{"id":3,"error":{"code":0,"message":"no handler for method: workspace/workspaceFolders"},"jsonrpc":"2.0"}

stdout:

Content-Length: 134

{"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"(17:12:36) matlabls: Log Directory: /tmp/matlabls_26511"}}Content-Length: 583

{"jsonrpc":"2.0","id":0,"result":{"capabilities":{"codeActionProvider":true,"completionProvider":{"triggerCharacters":[".","("," ",",","/","\\"]},"definitionProvider":true,"documentFormattingProvider":true,"documentRangeFormattingProvider":true,"executeCommandProvider":{"commands":["matlabls.lint.suppress.line","matlabls.lint.suppress.file"]},"foldingRangeProvider":true,"referencesProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"documentSymbolProvider":true,"renameProvider":{"prepareProvider":true},"documentHighlightProvider":true,"textDocumentSync":2}}}Content-Length: 201

{"jsonrpc":"2.0","id":0,"method":"client/registerCapability","params":{"registrations":[{"id":"91b68732-e3ec-49a1-bfb6-1202b45aad6f","method":"workspace/didChangeConfiguration","registerOptions":{}}]}}Content-Length: 101

{"jsonrpc":"2.0","id":1,"method":"workspace/configuration","params":{"items":[{"section":"MATLAB"}]}}Content-Length: 204

{"jsonrpc":"2.0","id":2,"method":"client/registerCapability","params":{"registrations":[{"id":"93246463-a499-485b-b7af-5c7110954b4d","method":"workspace/didChangeWorkspaceFolders","registerOptions":{}}]}}Content-Length: 103

{"jsonrpc":"2.0","method":"matlab/connection/update/server","params":{"connectionStatus":"connecting"}}Content-Length: 62

{"jsonrpc":"2.0","id":3,"method":"workspace/workspaceFolders"}

stderr:

(node:26511) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
/opt/matlab-language-server/out/index.js:43412
                        responsePromise.reject(new messages_1.ResponseError(error.code, error.message, error.data));
                                               ^

ResponseError: no handler for method: workspace/workspaceFolders
    at handleResponse (/opt/matlab-language-server/out/index.js:43412:48)
    at handleMessage (/opt/matlab-language-server/out/index.js:43192:13)
    at processMessageQueue (/opt/matlab-language-server/out/index.js:43209:17)
    at Immediate.<anonymous> (/opt/matlab-language-server/out/index.js:43181:13)
    at process.processImmediate (node:internal/timers:485:21) {
  code: 0,
  data: undefined
}

Node.js v22.21.1
Example `crush.json` lsp config for `matlab-language-server`

Example crush.json lsp config for matlab-language-server

{
  "$schema": "https://charm.land/crush.json",
  "lsp": {
    "matlab": {
      "command": "/usr/local/bin/matlab-language-server",
      "args": [
        "--stdio"
      ],
      "env": {
        "MLM_LICENSE_FILE": "27000@host"
      },
      "init_options": {
        "MATLAB": {
          "installPath": "/opt/matlab/R2025b",
          "indexWorkspace": true,
          "matlabConnectionTiming": "onStart",
          "telemetry": false,
          "signIn": true,
          "prewarmGraphics": false
        }
      }
    }
  },
  ...
}

Version

No response

Environment

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions