malli 2025-09-23

Today, I have a big disaster related to malli. I have a very complex schema for parsing incoming data, a kind of DSL. Lots of fields are declared as catn , orn and so on. These fields return pairs like [:integer 123] or [:string "foobar"] for example. When processing them, I have a common pattern like this:

(let [[tag value] parsed]
  (case tag
    :integer (process-as-integer value)
    :string (process-as-string value)))
quite many such fragments across the code base. Now, somebody has bumped malli and turned out, cant,orn and other parsing schemas return not pairs but a custom type Tag which is nothing but a defmap with the following keys:
{:key :integer :value 3000}
This map is completely different to a pair [:integer 3000] which I had before. Now I'm completely lost: the entire parsing & processing pipeline is broken due to another data format (vector -> map). Just wondering, is there is way to use old-style tags somehow? A flag maybe or something similar?

why did you update the version? can you roll back?

This is a matter of several internal libraries. Two or three of them use malli, and someone has pumped it. I can rollback of course but sooner or later somebody do it again

Fwiw, I also ran into this. I basically had to write compatibility for both pre and post versions of this breaking change. At the time I wasn’t able to find a ”feature flag” for compatibility.

I just wanted to stress how upset I am now with that breaking change, and honestly I would never anticipate it from such a good library

I hear you, I would have also hoped for some kind of a flag :) FWIW, I’m ex-metosin, so can’t really reach them, but maybe creating an issue out of this would be a start?

Yeah maybe... I'm thinking if it's possible to extend defrecord such that it supports nth

Actually, this tweak works fine, now the question is, if they OK to accept such a pr:

(defrecord Tag [key value]
  clojure.lang.Indexed
  (nth [_ i]
    (case (long i)
      0 key
      1 value
      (throw (new IndexOutOfBoundsException))))
  (nth [_ i not-found]
    (case (long i)
      0 key
      1 value
      not-found)))

I'm sorry for the breakage @igrishaev, we could've done a better job highlighting the breakage. I think we underestimated how many people are using parsing this heavily.