clj-kondo 2025-04-15

I'm seeing a bunch of spurious errors from kondo when run with a clean cache, which then disappear on subsequent runs. The errors are "unresolved symbol" findings from custom def* macros, so it seems as if :lint-as isn't being respected for *some* macros. Is this a known issue?

depends. where and how are the macros configured?

using :lint-as in config.edn

e.g. {:lint-as {my.ns.deffoo clojure.core/def}}

if it's a def like macros it's kind of expected that you first need to lint the other namespace before clj-kondo has the known vars in its cache

hm, so this is expected behavior? Feels quite unexpected to me

e.g. it means that running kondo in CI requires running it twice, unless we want to meticulously list files in "proper" lint order

"unresolved symbol" may be unexpected, I was thinking more about "unresolved var"

I need more details/repro to be able to say more about this

hard to repro since it's a large proprietary repo. I'll try, but in the meanwhile I'll just run kondo twice

can you show what the "unresolved symbol" code looks like? does it look like: (my-def foo <unresolved symbol: foo>)?

because that would indeed be unexpected if you configured with :lint-as in config.edn

should work the first time without linting any other files

I haven't looked through each error, but many of them are for a weird def with a bunch of additional stuff. But AFAIK that shouldn't affect linting via clojure.core/def?

(deffoo my-foo
  "docstring"
  [:thing1]
  "thing2"
  (fn [x y] ...)
  :bar "blah"
  :zotz {...})

in this case I'd get Unresolved symbol: my-foo

but only on first run with no cache

"with a bunch of additional stuff" might affect things for clojure.core/def since your def's syntax may be slightly different. you could try :lint-as clj-kondo.lint-as/def-catch-all which basically expects the var's symbol as the first argument and ignores all other errors

that wouldn't explain the caching behavior, would it?

the caching behavior also wouldn't affect unresolved-var if you lint all the files in one go, so I'm without guesses unless a repro can be made

unresolved symbol, not var. But yeah, that's understandable. I'll see if I can repro, but it may take time

i.e. "I may not get to it for months, depending on prioritization" :/

sorry I can't give you more to go on at the moment

in the meanwhile, it would be nice to be able to say something like clj-kondo --fail-level none ... for my "warmup" run

--dependencies is intended for that kind of usage

it's more specifically used for linting dependencies as a warm up round