malli

2026-02-16T08:48:32.837229Z

I am having some problems with multi schema and json-transform

(m/decode
   [:multi {:dispatch :type}
    [:kikka [:map
             [:type [:and [:= :kikka] :keyword]]
             [:kikka :int]]]]
   {:type "kikka" :kikka 1}
   (mt/json-transformer))
=> {:type "kikka", :kikka 1}
I'd have expected it to transform "kikka" to :kikka

juhoteperi 2026-02-16T08:53:07.298809Z

If you check validate, it should say it is invalid

juhoteperi 2026-02-16T08:53:19.324669Z

There should be explanation somewhere re multi dispatch and decoding

juhoteperi 2026-02-16T08:54:10.781499Z

Here the dispatch doesn't match any branch because the value isn't same type as dispatch values. And the information about the wanted type is only inside the dispatch branch.

juhoteperi 2026-02-16T08:54:17.578419Z

You need to decode the value at the multi schema level

juhoteperi 2026-02-16T08:54:58.081329Z

https://github.com/metosin/malli/?tab=readme-ov-file#multi-schemas ":dispatch values should be decoded before actual values:"

juhoteperi 2026-02-16T08:55:10.681579Z

(that sentence does sound a bit strange)

juhoteperi 2026-02-16T08:55:37.924639Z

":dispatch values should be decoded before using as dispatch value"

2026-02-16T08:56:08.345789Z

(m/encode [:multi {:dispatch :type}
             [:kikka [:map
                      [:type [:= :kikka]]
                      [:kikka :int]]]] {:type :kikka :kikka 1}
            (mt/json-transformer))
=> {:type "kikka", :kikka 1}
Ok so before taking that to a roundtrip I should handle those dispatch values separately

juhoteperi 2026-02-16T08:56:24.538199Z

just add the decode/string to :multi

juhoteperi 2026-02-16T08:57:11.881959Z

or I guess you could write :dispatch fn to coerce to correct type

2026-02-16T09:01:31.076679Z

(m/decode
   [:multi {:decode/string keyword :dispatch :type}
    [:kikka [:map
             [:type 
              [:and [:= :kikka] :keyword]]
             [:kikka :int]]]]
   {:type "kikka" :kikka 1}
   (mt/json-transformer))
this is not it, seems like

juhoteperi 2026-02-16T09:02:16.597079Z

decode/string at that level applies to the whole map

juhoteperi 2026-02-16T09:02:23.438569Z

check the readme example

2026-02-16T09:03:53.015439Z

Not this either.

(m/decode
   [:multi {:dispatch :type}
    [:kikka [:map
             [:type {:decode/string keyword}
              [:and [:= :kikka] :keyword]]
             [:kikka :int]]]]
   {:type "kikka" :kikka 1}
   (mt/json-transformer))
Thanks Juho, I think I need to look into this a little more, I'm probably just being dumb here

2026-02-16T09:04:14.589009Z

ah, its probably at the lower level still

juhoteperi 2026-02-16T09:04:25.258819Z

(m/decode [:multi {:dispatch :type :decode/string #(update % :type keyword)} .... )

2026-02-16T09:11:34.730049Z

I couldn't get that working but I resorted to adding a custom transformer that does it

2026-02-16T09:11:40.880819Z

Thanks for your help!