nrepl

ericdallo 2026-01-09T13:24:55.847949Z

hey @alexyakushev @bozhidar ๐Ÿ‘‹ @carloshernandez2.1b noticed that this https://github.com/nrepl/nrepl/pull/409 caused a breaking change for https://github.com/ericdallo/metrepl (althouth I believe we were not using a valid public api ๐Ÿ˜…) https://github.com/ericdallo/metrepl/blob/480b5e387d015bc044f91bf2770f9925fff2afd5/src/metrepl/metrics.clj#L81, basically, metrepl wants to know the middlewares loaded for metrics purpose, is there any better way to achieve that?

bozhidar 2026-01-09T13:28:49.160359Z

Can you point us to the code you're currently using so we can advice you how to update it?

ericdallo 2026-01-09T13:29:28.137709Z

yes, it's in the message, but here's the link: https://github.com/ericdallo/metrepl/blob/480b5e387d015bc044f91bf2770f9925fff2afd5/src/metrepl/metrics.clj#L81

carlos hernandez 2026-01-09T13:56:50.916839Z

Hey folks, Just to add to what @ericdallo said. Also the cider-list-nrepl-middleware functionality in Emacs stops working with the alpha version

bozhidar 2026-01-09T13:58:46.811149Z

> I've added a field middleware to the describe op response, it fits well there and achieves the same thing. So, basically now we have to use the describe op for this info. I'll update CIDER soon. This had slipped my mind.

bozhidar 2026-01-09T13:59:08.963939Z

Nice to see someone besides me knows of cider-list-nrepl-middleware. ๐Ÿ™‚

๐Ÿ˜ 1
oyakushev 2026-01-09T14:43:55.784269Z

Hello folks, I am sorry that this actually breaking change messed up your middleware. I hope it wouldn't be much of a hurdle to support older and newer nREPL version for you โ€“ you can check nrepl.version/version in the code to make appropriate decisions.

oyakushev 2026-01-09T14:44:37.531669Z

But overall this is an effort to streamline things and reduce the API surface. We hope the end result will be beneficial rather than detrimental.

ericdallo 2026-01-09T17:25:12.599759Z

no problem, thank you for the quick reply! we will take a look and try the describe approach

carlos hernandez 2026-01-09T14:53:55.079979Z

About https://github.com/nrepl/nrepl/releases/tag/v1.6.0-alpha1. I noticed that previously middleware used to be deduplicated on linearize-middleware-stack , but I tested now and it isn't. Maybe this could lead to unintentionally running middleware code multiple times. more on the ๐Ÿงต

danielsz 2026-02-28T13:05:17.147759Z

The warning still appears in the release version.

danielsz 2026-02-28T13:06:05.440639Z

Non cljs project. Zero reason to warn me about that.

danielsz 2026-02-28T13:06:38.208599Z

WARNING: Middleware #'cider.piggieback/wrap-cljs-repl is required by #'cider.nrepl/wrap-complete but is not present in middleware list.

carlos hernandez 2026-01-09T14:58:31.228859Z

For example: I might have configured in nrepl.edn :

{:middleware ^:concat [metrepl/middleware]}
And I always run with the repl with the repl alias which in a project happens to have that same middleware:
:repl {:main-opts ["-e" "(require,'ns1)" "-m" "nrepl.cmdline"  "--middleware" "[metrepl/middleware]"]}
Running the code twice will most likely have unintended side effects

oyakushev 2026-01-09T14:58:39.873899Z

Hey, good point, the deduplication is certainly necessary. Thanks for bringing this up.

๐Ÿ™Œ 1
oyakushev 2026-01-09T15:00:11.812889Z

Actually, I would suppose it is deduplicated by converting it to a set here https://github.com/nrepl/nrepl/blob/master/src/clojure/nrepl/middleware.clj#L95

oyakushev 2026-01-09T15:01:00.344819Z

Ah, I see now, it is not used later for iteration. Right.

1
carlos hernandez 2026-01-09T15:03:24.883459Z

To be completely sure I did the experiment and got this from the describe operation:

user> (require '[nrepl.core :as nrepl])
;; => nil
user> (defn check-middleware
  "Connect to an nREPL server and check for duplicate middleware.
   Takes a port number.
   Uses the ls-middleware op to get the current middleware stack."
  [port]
  (let [conn (nrepl/connect :port port)
        client (nrepl/client conn 1000)
        response (first (nrepl/message client {:op "describe"}))
        mw (:middleware response)]
    {:middleware mw
     :total (count mw)
     :unique (count (distinct mw))
     :duplicates? (not= (count mw) (count (distinct mw)))
     :duplicate-entries (->> (frequencies mw)
                             (filter #(> (val %) 1))
                             (into {}))}))
;; => #'user/check-middleware
user> (check-middleware 65326)
;; => {:middleware
 ["#'nrepl.middleware/wrap-describe"
  "#'nrepl.middleware.completion/wrap-completion"
  "#'nrepl.middleware.interruptible-eval/interruptible-eval"
  "#'"
  "#'nrepl.middleware.load-file/wrap-load-file"
  "#'nrepl.middleware.lookup/wrap-lookup"
  "#'nrepl.middleware.session/add-stdin"
  "#'cider.nrepl/wrap-apropos"
  "#'cider.nrepl/wrap-classpath"
  "#'cider.nrepl/wrap-clojuredocs"
  "#'cider.nrepl/wrap-complete"
  "#'cider.nrepl/wrap-content-type"
;; =>   "#'cider.nrepl/wrap-debug"
  "#'cider.nrepl/wrap-enlighten"
  "#'cider.nrepl/wrap-format"
  "#'cider.nrepl/wrap-info"
  "#'cider.nrepl/wrap-inspect"
  "#'cider.nrepl/wrap-log"
  "#'cider.nrepl/wrap-macroexpand"
  "#'cider.nrepl/wrap-ns"
  "#'cider.nrepl/wrap-out"
  "#'cider.nrepl/wrap-slurp"
  "#'cider.nrepl/wrap-profile"
  "#'cider.nrepl/wrap-refresh"
  "#'cider.nrepl/wrap-reload"
  "#'cider.nrepl/wrap-resource"
  "#'cider.nrepl/wrap-spec"
  "#'cider.nrepl/wrap-stacktrace"
  "#'cider.nrepl/wrap-test"
;; =>   "#'metrepl.middleware.tests-metrics/wrap-tests-metrics"
  "#'cider.nrepl/wrap-trace"
  "#'cider.nrepl/wrap-undef"
  "#'cider.nrepl/wrap-tracker"
  "#'cider.nrepl/wrap-version"
  "#'cider.nrepl/wrap-xref"
  "#'flow-storm.nrepl.middleware/wrap-flow-storm"
  "#'nrepl.middleware.caught/wrap-caught"
  "#'nrepl.middleware.print/wrap-print"
  "#'nrepl.middleware.session/session"
  "#'metrepl.middleware.op-metrics/wrap-op-metrics"
  "#'metrepl.middleware.op-metrics/wrap-op-metrics"
;; =>   "#'metrepl.middleware.tests-metrics/wrap-tests-metrics"
  "#'metrepl.middleware.op-metrics/wrap-op-metrics"
  "#'metrepl.middleware.tests-metrics/wrap-tests-metrics"
  "#'refactor-nrepl.middleware/wrap-refactor"],
 :total 45,
 :unique 41,
 :duplicates? true,
 :duplicate-entries
 {"#'metrepl.middleware.tests-metrics/wrap-tests-metrics" 3,
;; =>   "#'metrepl.middleware.op-metrics/wrap-op-metrics" 3}}
user> 

oyakushev 2026-01-09T15:17:19.500879Z

1.6.0-alpha2 just hit.

carlos hernandez 2026-01-09T15:18:08.144999Z

Thank you!

โค๏ธ 1
danielsz 2026-01-09T19:49:10.422249Z

The transition from 1.5.2 to 1.6.0-alpha2 introduced a change that in my setup generates an error: Execution error (ExceptionInfo) at nrepl.middleware/extended-descriptors$iter$fn (middleware.clj:103). Middleware #'cider.piggieback/wrap-cljs-repl is required by #'cider.nrepl/wrap-complete but is not present in middleware list. My project is pure Clojure, not Clojurescript, so the reference to piggieback is suspect.

oyakushev 2026-01-09T19:57:14.748899Z

Hey, sorry for that, this alpha was not really intended to be rolled out to all users already, I'm rolling it back right now. But it will take a few hours to update on MELPA, so for the time being, please downgrade back to 1.5.2 by doing M-x customize-variable cider-injected-nrepl-version.

danielsz 2026-01-09T19:57:54.126969Z

Sure, no problem at all. I am sorry in that case.

โค๏ธ 1
danielsz 2026-01-09T19:58:07.866039Z

Thank you for your hard work.

โค๏ธ 1