lsp 2026-09-25

i've run into a funny bug that i don't quite understand. i :required a namespace and used a function from it inside the body of a protocol method in a defrecord. i had the wrong number of arguments, but clojure-lsp didn't warn me about it. if i move the function call out of the protocol method body, it is correctly linted and an expected "invalid number of args" error arises. if i use the function outside of the protocol method body as well as inside the protocol method body, it is correctly linted and the error arises. (code in thread)

perhaps this is more a clj-kondo issue?

if you can repro it on the command line without lsp, that would be interesting

clj-kondo correclty lints it, which is why this surprised me

hmm maybe it's something to do with :lsp/publish-diagnostics

from the readme:

noah ~/personal/lsp-example
jj:[@ vktvxuym 55e1665d]
$ rm -rf .clj-kondo/.cache .lsp/.cache
noah ~/personal/lsp-example
jj:[@ vktvxuym 55e1665d]
$ clojure-lsp diagnostics
[ 99%] Project analyzed            Finding diagnostics...
src/lsp/core.clj:9:10: error: [invalid-arity] lsp.other/one-arg is called with 2 args but expects 1
src/lsp/core.clj:5:4: info: [clojure-lsp/unused-public-var] Unused public var 'lsp.core/f'
src/lsp/core.clj:7:12: info: [clojure-lsp/unused-public-var] Unused public var 'lsp.core/R'
noah ~/personal/lsp-example
jj:[@ vktvxuym 55e1665d]
$ nvim src/lsp/core.clj
noah ~/personal/lsp-example
jj:[@ vktvxuym 55e1665d]
$ clojure-lsp diagnostics
[ 99%] Project analyzed            Finding diagnostics...
src/lsp/core.clj:5:4: info: [clojure-lsp/unused-public-var] Unused public var 'lsp.core/f'
src/lsp/core.clj:7:12: info: [clojure-lsp/unused-public-var] Unused public var 'lsp.core/R'

and if i tail the clojure-lsp log, i see that textDocument/publishDiagnostics doesn't send over the invalid-arity anymore:

2026-09-25T16:48:52.441Z  DEBUG [clojure-lsp.server:61] - [Trace - 2026-09-25T16:48:52.441Z] Sending notification 'textDocument/publishDiagnostics'
Params: {
  "uri" : "file:///Users/noah.bogart/personal/lsp-example/src/lsp/core.clj",
  "diagnostics" : [ {
    "range" : {
      "start" : {
        "line" : 4,
        "character" : 3
      },
      "end" : {
        "line" : 4,
        "character" : 4
      }
    },
    "severity" : 3,
    "message" : "Unused public var 'lsp.core/f'",
    "code" : "clojure-lsp/unused-public-var",
    "source" : "clojure-lsp",
    "tags" : [ 1 ]
  }, {
    "range" : {
      "start" : {
        "line" : 6,
        "character" : 11
      },
      "end" : {
        "line" : 6,
        "character" : 12
      }
    },
    "severity" : 3,
    "message" : "Unused public var 'lsp.core/R'",
    "code" : "clojure-lsp/unused-public-var",
    "source" : "clojure-lsp",
    "tags" : [ 1 ]
  } ]
}

so something strange is happening here, but i'm not sure what

and then if i add the same invalid call outside of the protocl method body, the error now appears for both sites:

2026-09-25T16:53:59.960Z  DEBUG [clojure-lsp.server:61] - [Trace - 2026-09-25T16:53:59.960Z] Sending notification 'textDocument/publishDiagnostics'
Params: {
  "uri" : "file:///Users/noah.bogart/personal/lsp-example/src/lsp/core.clj",
  "diagnostics" : [ {
    "range" : {
      "start" : {
        "line" : 6,
        "character" : 0
      },
      "end" : {
        "line" : 6,
        "character" : 15
      }
    },
    "tags" : [ ],
    "message" : "lsp.other/one-arg is called with 2 args but expects 1",
    "code" : "invalid-arity",
    "langs" : [ ],
    "severity" : 1,
    "source" : "clj-kondo"
  }, {
    "range" : {
      "start" : {
        "line" : 9,
        "character" : 9
      },
      "end" : {
        "line" : 9,
        "character" : 24
      }
    },
    "tags" : [ ],
    "message" : "lsp.other/one-arg is called with 2 args but expects 1",
    "code" : "invalid-arity",
    "langs" : [ ],
    "severity" : 1,
    "source" : "clj-kondo"
  }, {
    "range" : {
      "start" : {
        "line" : 4,
        "character" : 3
      },
      "end" : {
        "line" : 4,
        "character" : 4
      }
    },
    "severity" : 3,
    "message" : "Unused public var 'lsp.core/f'",
    "code" : "clojure-lsp/unused-public-var",
    "source" : "clojure-lsp",
    "tags" : [ 1 ]
  }, {
    "range" : {
      "start" : {
        "line" : 7,
        "character" : 11
      },
      "end" : {
        "line" : 7,
        "character" : 12
      }
    },
    "severity" : 3,
    "message" : "Unused public var 'lsp.core/R'",
    "code" : "clojure-lsp/unused-public-var",
    "source" : "clojure-lsp",
    "tags" : [ 1 ]
  } ]
}

can you try rm -rf .lsp/.cache && clojure-lsp diagnostics and check if behaves like kondo? (it's about time I add a --no-cache flag for those testings)

if you look at my terminal output in the message above that says "from the readme" (or look at the readme in the linked repo), i start with showing that clojure-lsp diagnostics correctly reports the error, and it's only once i've run clojure-lsp as an lsp from my editor does it stop flagging that

after a closer look, it seems it's a kondo cache bug: If a namespace is only used through calls inside protocol impl methods, clj-kondo doesn't load it from the cache, so invalid-arity isn't reported, reproed as:

$ echo '(ns repro (:require [clojure.string :as str])) (defrecord R [] Object (toString [_] (str/join)))' | clj-kondo --lint -
linting took 12ms, errors: 0, warnings: 0
I believe this repro in your repro noah:
$ git clone  && cd lsp-repro && mkdir .clj-kondo
$ clj-kondo --lint src
src/lsp/core.clj:9:10: error: lsp.other/one-arg is called with 2 args but expects 1
$ clj-kondo --lint src/lsp/core.clj
linting took 16ms, errors: 0, warnings: 0
I believe should happen with reify, deftype, extend-protocol and maybe others

👀 1

oh thank you for the smaller repro

i'll open a github issue on clj-kondo with this

👍 1