Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match.
i would expect the json key that exactly matches the tag (fieldSETid) to be unmarshalled to the struct (in this case, it should be "sdkgjfhdfsgj") in any json key ordering.
What did you see instead?
the last case-insensitive match encountered in the json object is the accepted value. this is what differs this from this issue: #11673
this would be completely acceptable if it was deterministic every time. however, json keys are not deterministic (in fact, my understanding is that golang's own marshal does not guarantee key order). this can lead to non-deterministic differences in unmarshal behavior, and there's not really a workaround other than changing the incoming payload (which may not be possible due to the fact that it may be generated using a system that does not have deterministic key order).
The text was updated successfully, but these errors were encountered:
changed the title
encoding/jsonunmarshal case insensitive match can lead to nondeterministic behaviorJan 31, 2020
I think this is a duplicate of #14750; in particular, see my proposed solution at #14750 (comment). That would essentially be amending the docs to reflect the behavior we have had for years.
The alternative would be to change the implementation to reflect the documentation - that is, to give preference to the case sensitive match, no matter the order. However, I worry that that could easily break existing programs in subtle ways.
In any case, I think the discussion should continue in that previous issue.
yeah, i agree that the godoc is inconsistent, but i think this is a bug regardless of what the docs say. imo, the correct bug fix is not changing the docs, it's to change the behavior. i don't think it was ever the intention to cause non-deterministic behavior. in certain scenarios, safely unmarshalling the correct key is not supported, barring writing a custom unmarshaller. if there was a flag or something that you could specify to force the match to be case sensitive, then this would be fine. but as long as order determines which key gets unmarshalled, this is going to be an unsafe and unpredictable operation. i'm fine with moving the discussion over to that issue though. thanks for pointing that out to me.