Turns out it was my json encoders and decoders at fault, as they did not encode and decode the same json.
decodeItems : Decode.Decoder (List ( String, String ))
decodeItems =
Decode.at [ "detail", "value" ] <|
Decode.list <|
Decode.map2 (,) Decode.string Decode.string
encodeItems : List ( String, String ) -> Encode.Value
encodeItems items =
Encode.list
(List.map (\( idx, val ) -> Encode.list [ Encode.string idx, Encode.string val ]) items)
I changed the decoder to:
decodeItems : Decode.Decoder (List ( String, String ))
decodeItems =
Decode.at [ "detail", "value" ] <|
Decode.list <|
Decode.map2 (,) (Decode.index 0 Decode.string) (Decode.index 1 Decode.string)
and it works. I seem to have opted for a slightly non-standard encoding of a dictionary as an array of arrays, rather than as a json object with name/value fields, but I can fix that.
Strange that it worked in 0.17, I guess the json parsing rules got tightened up a bit.