clj-kondo 2026-07-23

@borkdude thoughts on adding a linter to catch destructuring in if-let and when-let - I caught a couple of cases where this kind of code was not supposed to execute:

(when-let [{:keys [sth] } (get-sth)] 
   (do-sth sth))
but get-sth returns {:foo :bar} or {:sth nil}. It's a knowledge check really, so it should be an explicit opt-in. I'm more than happy to contribute it but I think it's better to get your thoughts before I commit

Give me the complete context including do-sth and with the errors you expect in which place, since I don't fully grasp what you mean

Of course, it's code like this:

(when-let [{:keys [address-normalized zip-code]} (svc.address-lookup/resolve al-client {:address "...." })]
   (model.profile/update-address conn {:user-id id :address address-normalized :zipcode zip-code}))
as it happens, the bug was that svc.address-lookup/resolve would sometimes return a map with missing fields, rather than nil to indicate that address couldn't be resolved, which then resulted in invalid data being written to the db. Having a warning from the linter would at least signal that resolve needs to retun nil on lookup failure.

can you make a standalone example please

a complete file with expected output

ah sure, if it's better for you - I can open an issue in GH with a synthetic example

no, to just discuss the problem, it's fine to make a standalone example here, but I just don't understand incomplete examples well. also I can't check if clj-kondo already has it on master

A complete example is the contents of a .clj file you can throw at clj-kondo, including an ns form if necessary

gotcha, I'll share something later today

🙏 1

I think this is as simple as it gets:

(ns lint-test)

(defn get-address []
  {:address nil})

(defn store-address [store]
  ;; if enabled, this should warn about destructuring in when-let
  (when-let [{:keys [address]} (get-address)]
    (swap! store assoc :address address)))

(let [store (atom {})]
  (store-address store)
  (assert (empty? @store)) ;; will throw
  )
linting attempt:
# clj-kondo --version
clj-kondo v2026.05.25
# clj-kondo --lint ./lint_test.clj
linting took 17ms, errors: 0, warnings: 0

Have you tried that with the latest master version of Kondo @lukaszkorecki? I think that would get detected now.

That's with the latest nightly on LSP which uses the master build of Kondo.

ah, neat - I missed that this was implemented already, I had a quick look on GH but looks like I wasn't thorough enough

sorry for the noise!

No worries. There's been a huge amount of additional inference added since the last full release. @borkdude rocks! 💪🏻 🚀

I don't know when he sleeps (if he does), I can't keep up with all the new stuff (that clj -> elisp thing looks very neat)

👍🏻 1

...that said - I'm looking at the doc for "constant condition", it would be worth flagging that it will flag that type of usage of if-let/`when-let` - currently they're not included in examples

if-let / when-let are default clojure macros with conditions, all of those should be included. if it's missing a case let me know