Skip to content

Language server raises exception when client does not have any configuration settings to provide it. #2002

@cowboyd

Description

@cowboyd

Error: Request textDocument/codeAction failed with message: Cannot read properties of null (reading 'workingDirectory')

I'm trying to get the vscode-eslint server working with the Emacs eglot client. However, it is raising an exception because of what is apparently a null settings for the requested file. If I understand the spec correctly however, Eglot's behavior is ok.

If the client can’t provide a configuration setting for a given scope then null needs to be present in the returned array.

Here is the full transcript of the conversation between Eglot and vscode-eslint. As you can see at the end, it apparently requests the configuration as part of responding to the textDocument/codeAction request. When Eglot responds that is has no further configuration available by returning null, the textDocument/codeAction request fails with the above exception.

One further note: Eglot does issue this warning as part of the transcript: [eglot] (warning) Server tried to register unsupported capability ‘workspace/didChangeWorkspaceFolders’.

In the transcript --> represents an outgoing request, and <-- represents a response to a previous request. Notifications are always ongoing -->


 --> [client2server.request] [ "vscode-eslint-language-server" ] initialize [
   {
     processId: 34058,
     clientInfo: { name: "Eglot", version: "1.18.0.20250408.74617" },
     rootPath: "/Users/cowboyd/Code/@cowboyd/react-ts-eslint-prettier-sample/",
     rootUri: "file:///Users/cowboyd/Code/@cowboyd/react-ts-eslint-prettier-sample",
     initializationOptions: {},
     capabilities: {
       workspace: {
         applyEdit: true,
         executeCommand: { dynamicRegistration: false },
         workspaceEdit: { documentChanges: true },
         didChangeWatchedFiles: { dynamicRegistration: true },
         symbol: { dynamicRegistration: false },
         configuration: true,
         workspaceFolders: true
       },
       textDocument: {
         synchronization: {
           dynamicRegistration: false,
           willSave: true,
           willSaveWaitUntil: true,
           didSave: true
         },
         completion: {
           dynamicRegistration: false,
           completionItem: [Object],
           contextSupport: true
         },
         hover: { dynamicRegistration: false, contentFormat: [Array] },
         signatureHelp: { dynamicRegistration: false, signatureInformation: [Object] },
         references: { dynamicRegistration: false },
         definition: { dynamicRegistration: false, linkSupport: true },
         declaration: { dynamicRegistration: false, linkSupport: true },
         implementation: { dynamicRegistration: false, linkSupport: true },
         typeDefinition: { dynamicRegistration: false, linkSupport: true },
         documentSymbol: {
           dynamicRegistration: false,
           hierarchicalDocumentSymbolSupport: true,
           symbolKind: [Object]
         },
         documentHighlight: { dynamicRegistration: false },
         codeAction: {
           dynamicRegistration: false,
           resolveSupport: [Object],
           dataSupport: true,
           codeActionLiteralSupport: [Object],
           isPreferredSupport: true
         },
         formatting: { dynamicRegistration: false },
         rangeFormatting: { dynamicRegistration: false },
         rename: { dynamicRegistration: false },
         inlayHint: { dynamicRegistration: false },
         callHierarchy: { dynamicRegistration: false },
         typeHierarchy: { dynamicRegistration: false },
         publishDiagnostics: {
           relatedInformation: false,
           codeDescriptionSupport: false,
           tagSupport: [Object]
         }
       },
       window: {
         showDocument: { support: true },
         showMessage: { messageActionItem: [Object] },
         workDoneProgress: true
       },
       general: { positionEncodings: [ "utf-32", "utf-8", "utf-16" ] },
       experimental: {}
     },
     workspaceFolders: [
       {
         uri: "file:///Users/cowboyd/Code/@cowboyd/react-ts-eslint-prettier-sample",
         name: "~/Code/@cowboyd/react-ts-eslint-prettier-sample/"
       }
     ]
   },
   MutableToken { _isCancelled: false }
 ]
 --> [server2client.notify] vscode-eslint-language-server window/logMessage [ { type: 3, message: "ESLint server running in node v22.9.0" } ]
 <-- [client2server.request] [ "vscode-eslint-language-server" ] initialize {
   serverInfo: { name: "lspx", version: "0.1.0" },
   capabilities: {
     textDocumentSync: {
       openClose: true,
       change: 2,
       willSaveWaitUntil: false,
       save: { includeText: false }
     },
     workspace: { workspaceFolders: { supported: true } },
     executeCommandProvider: {
       commands: [
         "eslint.applySingleFix",
         "eslint.applySuggestion",
         "eslint.applySameFixes",
         "eslint.applyAllFixes",
         "eslint.applyDisableLine",
         "eslint.applyDisableFile",
         "eslint.openRuleDoc"
       ]
     },
     diagnosticProvider: {
       identifier: "eslint",
       interFileDependencies: false,
       workspaceDiagnostics: false
     },
     codeActionProvider: { codeActionKinds: [ "quickfix", "source.fixAll.eslint" ] }
   }
 }
 --> [client2server.notify] [ "vscode-eslint-language-server" ] initialized [ {} ]
 --> [client2server.notify] [ "vscode-eslint-language-server" ] textDocument/didOpen [
   {
     textDocument: {
       uri: "file:///Users/cowboyd/Code/@cowboyd/react-ts-eslint-prettier-sample/src/App.tsx",
       version: 0,
       languageId: "typescript",
       text: 'import { useState } from "react";\n' +
         'import reactLogo from "./assets/react.svg";\n' +
         'import viteLogo from "/vite.svg";\n' +
         'import "./App.css";\n' +
         "\n" +
         "const emptyFunc = (_, a) => {\n" +
         "  return a;\n" +
         "};\n" +
         "\n" +
         "function App() {\n" +
         "           const [count, setCount] = useState(0);\n" +
         "\n" +
         "       const x: number = '1234';\n" +
         "\n" +
         "  return (\n" +
         "          <>\n" +
         "      <div>\n" +
         '        <a href="https://vite.dev" target="_blank">\n' +
         '          <img src={viteLogo} className="logo" alt="" />\n' +
         "        </a>\n" +
         '        <a href="https://react.dev" target="_blank">\n' +
         '          <img src={reactLogo} className="logo react" alt="React logo" />\n' +
         "        </a>\n" +
         "      </div>\n" +
         "      <h1>Vite + React</h1>\n" +
         '      <div className="card">\n' +
         "        <button onClick={() => setCount((count) => count + 1)}>\n" +
         "          count is {count}\n" +
         "        </button>\n" +
         "        <p>\n" +
         "          Edit <code>src/App.tsx</code> and save to test HMR\n" +
         "        </p>\n" +
         "      </div>\n" +
         '      <p className="read-the-docs">\n' +
         "        Click on the Vite and React logos to learn more\n" +
         "      </p>\n" +
         "    </>\n" +
         "  );\n" +
         "}\n" +
         "\n" +
         "export default App;\n"
     }
   }
 ]
 --> [client2server.notify] [ "vscode-eslint-language-server" ] workspace/didChangeConfiguration [ { settings: {} } ]
 --> [server2client.request] vscode-eslint-language-server client/registerCapability [
   {
     registrations: [
       {
         id: "a9cd965b-6aff-4307-930d-ba22fb57dde0",
         method: "workspace/didChangeWorkspaceFolders",
         registerOptions: {}
       }
     ]
   },
   MutableToken { _isCancelled: false }
 ]
 <-- [server2client.request] vscode-eslint-language-server client/registerCapability null
 --> [client2server.request] [ "vscode-eslint-language-server" ] textDocument/codeAction [
   {
     textDocument: {
       uri: "file:///Users/cowboyd/Code/@cowboyd/react-ts-eslint-prettier-sample/src/App.tsx"
     },
     range: {
       start: { line: 34, character: 51 },
       end: { line: 34, character: 55 }
     },
     context: { diagnostics: [], triggerKind: 2 }
   },
   MutableToken { _isCancelled: false }
 ]
 --> [server2client.request] vscode-eslint-language-server workspace/configuration [
   {
     items: [
       {
         scopeUri: "file:///Users/cowboyd/Code/@cowboyd/react-ts-eslint-prettier-sample/src/App.tsx",
         section: ""
       }
     ]
   },
   MutableToken { _isCancelled: false }
 ]
 <-- [server2client.request] vscode-eslint-language-server workspace/configuration [ null ]
 Error: Request textDocument/codeAction failed with message: Cannot read properties of null (reading 'workingDirectory')
     at handleResponse (file:///var/folders/zs/m38wmycs4pj6ymtkk3cjrp0w0000gn/T/deno-compile-lspx/.deno_compile_node_modules/localhost/vscode-jsonrpc/8.2.1/lib/common/connection.js:565:48)
     at handleMessage (file:///var/folders/zs/m38wmycs4pj6ymtkk3cjrp0w0000gn/T/deno-compile-lspx/.deno_compile_node_modules/localhost/vscode-jsonrpc/8.2.1/lib/common/connection.js:345:13)
     at processMessageQueue (file:///var/folders/zs/m38wmycs4pj6ymtkk3cjrp0w0000gn/T/deno-compile-lspx/.deno_compile_node_modules/localhost/vscode-jsonrpc/8.2.1/lib/common/connection.js:362:17)
     at file:///var/folders/zs/m38wmycs4pj6ymtkk3cjrp0w0000gn/T/deno-compile-lspx/.deno_compile_node_modules/localhost/vscode-jsonrpc/8.2.1/lib/common/connection.js:334:13
     at ext:deno_web/02_timers.js:35:14
     at eventLoopTick (ext:core/01_core.js:213:13) {
   code: -32603,
   data: undefined
 }

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature-requestRequest for new features or functionalityhelp wantedIssues identified as good community contribution opportunities

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions