cider

Ed 2025-06-20T15:19:46.805249Z

Hi. I've weirdly started getting an error when trying to eval some via C-c C-c, etc: nrepl-dict: An even number of KEY-VALS is needed to build a dict object - details in 🧵

✅ 1
Ed 2025-06-20T15:20:07.494529Z

This randomly started happening when I'm connecting to a project that has a lot of deps and uses shadow-cljs to start an nREPL server (with npx shadow-cljs -A:dev:test:tools watch :alias and then I run M-x cider-connect:

;; Connected to nREPL server - 
;; CIDER 1.19.0-snapshot (package: 20250619.1159), nREPL 1.1.0
;; Clojure 1.12.1, Java 24.0.1
(I upgraded everything just in case) C-c C-k works to load the main namespace, but when I try and start the server by eval some code, I get what I assue is some basic middleware error. I tried the same thing on a different project (that I start with clj -M,,,) and I don't get the same error. In the project that doesn't work, if I run M-x cider-list-nrepl-middleware I get:
Currently loaded middleware:
But in the project that works I get:
Currently loaded middleware:
* #'nrepl.middleware/wrap-describe
* #'nrepl.middleware.dynamic-loader/wrap-dynamic-loader
* #'nrepl.middleware.completion/wrap-completion
* #'cider.nrepl/wrap-ns
* #'cider.nrepl/wrap-test
* #'cider.nrepl/wrap-log
* #'cider.nrepl/wrap-refresh
* #'nrepl.middleware.interruptible-eval/interruptible-eval
* #'nrepl.middleware.sideloader/wrap-sideloader
* #'nrepl.middleware.load-file/wrap-load-file
* #'nrepl.middleware.session/add-stdin
* #'cider.nrepl/wrap-info
* #'cider.nrepl/wrap-xref
* #'cider.nrepl/wrap-apropos
* #'cider.nrepl/wrap-profile
* #'cider.nrepl/wrap-version
* #'cider.nrepl/wrap-trace
* #'cider.nrepl/wrap-complete
* #'cider.nrepl/wrap-classpath
* #'cider.nrepl/wrap-content-type
* #'cider.nrepl/wrap-clojuredocs
* #'cider.nrepl/wrap-resource
* #'cider.nrepl/wrap-macroexpand
* #'cider.nrepl/wrap-undef
* #'cider.nrepl/wrap-reload
* #'cider.nrepl/wrap-spec
* #'cider.nrepl/wrap-format
* #'cider.nrepl/wrap-stacktrace
* #'cider.nrepl/wrap-slurp
* #'nrepl.middleware.lookup/wrap-lookup
* #'cider.nrepl/wrap-debug
* #'cider.nrepl/wrap-enlighten
* #'cider.piggieback/wrap-cljs-repl
* #'cider.nrepl/wrap-tracker
* #'cider.nrepl/wrap-out
* #'cider.nrepl/wrap-inspect
* #'nrepl.middleware.session/session
* #'nrepl.middleware.caught/wrap-caught
* #'nrepl.middleware.print/wrap-print
I don't see any obvious errors about not being able to load middleware when the shadow-cljs project starts. How do I go about working out whats breaking?

dpsutton 2025-06-20T15:21:20.251679Z

there’s something like nrepl-toggle-message or similar. that will show the literal messages going across. hopefully that will let us see which list which represents a map has an uneven number of keys

Ed 2025-06-20T15:23:00.324979Z

nrepl-toggle-message-logging?

dpsutton 2025-06-20T15:23:35.986939Z

yes that’s the one

dpsutton 2025-06-20T15:23:49.352359Z

will start logging the messages into a new buffer

Ed 2025-06-20T15:25:56.584289Z

I have a buffer called *nrepl-messages trimly/trimly:localhost:8200(clj)* but nothing new get's written into it when I try and eval something

dpsutton 2025-06-20T15:26:15.881829Z

kill the connection and then jack in again?

dpsutton 2025-06-20T15:26:27.012729Z

an error might have already messed everything up

Ed 2025-06-20T15:28:57.021779Z

I get some messages during startup (that I can paste here) but again, nothing get's added when I try and eval (+ 1 2 3)

Ed 2025-06-20T15:29:16.674999Z

log:

(-->
  id             "1"
  op             "clone"
  time-stamp     "2025-06-20 16:26:41.938886702"
  client-name    "CIDER"
  client-version "1.19.0-snapshot"
)
(<--
  id          "1"
  session     "8c452326-5ecf-470e-ae39-70a65623fa78"
  time-stamp  "2025-06-20 16:26:41.946821806"
  new-session "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  status      ("done")
)
(-->
  id             "2"
  op             "clone"
  time-stamp     "2025-06-20 16:26:41.959667601"
  client-name    "CIDER"
  client-version "1.19.0-snapshot"
)
(<--
  id          "2"
  session     "e7377853-c8d2-4969-bc6e-e20c6472bb3c"
  time-stamp  "2025-06-20 16:26:41.961188008"
  new-session "abe3aeb6-fdca-4162-97dc-ecfd39ab432d"
  status      ("done")
)
(-->
  id         "3"
  op         "describe"
  session    "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp "2025-06-20 16:26:41.980516269"
)
(<--
  id         "3"
  session    "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp "2025-06-20 16:26:41.985971291"
  aux        (dict ...)
  ops        (dict ...)
  status     ("done")
  versions   (dict ...)
)
(-->
  id                                 "4"
  op                                 "eval"
  session                            "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp                         "2025-06-20 16:26:42.003541838"
  code                               "(when-let [requires (resolve 'clojure.main/repl-requires)]
 ..."
  column                             1

  file                               "*cider-repl trimly/trimly:localhost:8200(clj)*"
  inhibit-cider-middleware           "true"
  line                               10

  nrepl.middleware.print/buffer-size 4096

  nrepl.middleware.print/options     (dict ...)
  nrepl.middleware.print/print       "cider.nrepl.pprint/pprint"
  nrepl.middleware.print/quota       1048576

  nrepl.middleware.print/stream?     "1"
)
(<--
  id         "4"
  session    "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp "2025-06-20 16:26:42.019270834"
  value      "nil"
)
(<--
  id         "4"
  session    "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp "2025-06-20 16:26:42.051604582"
  ns         "shadow.user"
)
(<--
  id         "4"
  session    "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp "2025-06-20 16:26:42.051710937"
  status     ("done")
)
(-->
  id         "5"
  op         "out-subscribe"
  session    "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp "2025-06-20 16:26:42.051884279"
)
(-->
  id                                 "6"
  op                                 "init-debugger"
  session                            "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp                         "2025-06-20 16:26:42.052040348"
  nrepl.middleware.print/buffer-size 4096

  nrepl.middleware.print/options     (dict ...)
  nrepl.middleware.print/print       "cider.nrepl.pprint/pprint"
  nrepl.middleware.print/quota       1048576

  nrepl.middleware.print/stream?     "1"
)
(<--
  id            "5"
  session       "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  time-stamp    "2025-06-20 16:26:42.066612732"
  out-subscribe "cd2c6393-ce8f-46c9-81cb-a82eddf02aa1"
  status        ("done")
)

Ed 2025-06-20T15:30:05.673659Z

C-c C-k does however add some stuff to the buffer

Ed 2025-06-20T15:30:31.274329Z

which implies to me the error is happening before it even tries to send something to the nrepl connection?

dpsutton 2025-06-20T15:30:57.383759Z

maybe so. there’s an m-x toggle-debug-on-error or similar that could perhaps help out

Ed 2025-06-20T15:31:46.147619Z

yes - thanks ... that's useful 😉

Ed 2025-06-20T15:32:43.147489Z

still not sure why emacs thinks there's no middleware loaded

Ed 2025-06-20T15:44:42.071029Z

it seems like it's this code

(defun cider--nrepl-pr-request-plist ()
  "Map to merge into requests that do not require pretty printing."
  (let ((print-options (thread-last
                         cider-print-options
                         (map-pairs)
                         (seq-mapcat #'identity)
                         (apply #'nrepl-dict))))
    `("nrepl.middleware.print/print" "cider.nrepl.pprint/pr"
      "nrepl.middleware.print/stream?" nil
      ,@(unless (nrepl-dict-empty-p print-options)
          `("nrepl.middleware.print/options" ,print-options))
      ,@(when cider-print-quota
          `("nrepl.middleware.print/quota" ,cider-print-quota)))))
which is triggering the error. I see nrepl-dict(("print-length" nil)) in the stack trace and it turns out i had a (cider-print-options (("print-length" nil))) in the dir-locals for that project. Removed and the eval works again. I'm not sure how this worked last week. I'm not sure when that stopped working but I don't think I updated anything between it working and now.

Ed 2025-06-20T15:45:22.125929Z

Many thanks @dpsutton

👍 1
enn 2025-06-20T15:34:43.096919Z

Since :main-opts from multiple aliases don't combine, the approach suggested in the CIDER "https://docs.cider.mx/cider/basics/middleware_setup.html#using-tools-deps" docs of adding an alias in ~/.clojure/deps.edn to load cider-nrepl does not work if you are starting your project using an alias that also has :main-opts used to run the application. Of course you could combine the :main-opts manually in your alias definition in your project's deps.edn, but that's not optimal: for example, in the fairly common case that a project has some contributors who use CIDER and some who use other tools. I don't want to use cider-jack-in because I want to start using the project alias and -main to start the application. But then I want to be able to cider-connect with full cider-nrepl functionality once it's running. How are other folks thinking about this?

dpsutton 2025-06-20T15:50:39.995869Z

mains are jealous. I think it’s always worth letting the repl be the main that you use in your editor and then have an easy way to start your application from the repl. often this is calling the other -main but without any thread-join or system/exits involved

☝️ 1