Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/json: marshaling nil value stored in interface value doesn't omitempty #16750

Closed
jnross opened this issue Aug 16, 2016 · 6 comments
Closed
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@jnross
Copy link

jnross commented Aug 16, 2016

  1. What version of Go are you using (go version)?
    1.7, also verified with 1.6.3
  2. What operating system and processor architecture are you using (go env)?
    darwin/amd64
  3. What did you do?
    I have a struct "result" defined with one of the members "Err" as an interface type "error". The json annotation specifies "omitempty". I define another struct type concreteError which implements this interface on the pointer receiver (i.e. *concreteError implements the interface).

If I assign a nil pointer variable to result.Err, the field is not omitted from the marshaled JSON as expected. Instead the field is marshaled as a JSON null.

If I assign the nil literal to result.Err, the field is omitted from the marshaled JSON as expected

This issue is clearly demonstrated here: https://play.golang.org/p/uw6jvKN-qX

  1. What did you expect to see?
    A nil interface value should be omitted from the marshaled JSON when the field is annotated with "omitempty"
  2. What did you see instead?
    The nil interface value was not omitted.
@dgryski
Copy link
Contributor

dgryski commented Aug 17, 2016

This looks like fallout from https://golang.org/doc/faq#nil_error

@jnross
Copy link
Author

jnross commented Aug 17, 2016

Yes, that must be the case. Perhaps the JSON marshaller should use reflect.ValueOf(res.Err).IsNil() to determine whether an interface is empty and should be omitted per the annotation.

@jnross
Copy link
Author

jnross commented Aug 17, 2016

This appears to resolve the issue: jnross@36aa259

I'll see about contributing this patch directly per the instructions here: https://golang.org/doc/contribute.html

@odeke-em odeke-em changed the title json.Marshal struct with interface member doesn't omitempty nil values encoding/json: marshaling nil value stored in interface value doesn't omitempty Aug 18, 2016
@quentinmit quentinmit added this to the Go1.8Maybe milestone Sep 6, 2016
@quentinmit quentinmit added the NeedsFix The path to resolution is known, but the work has not been done. label Oct 10, 2016
@rsc
Copy link
Contributor

rsc commented Oct 20, 2016

Working as intended. If you have

I int `json:",omitempty"
S string `json:",omitempty"`
J interface{} `json:",omitempty"

Then if I = 0 it gets omitted, or if S is "" it gets omitted, or if J is nil it gets omitted. But if J is 0 or "", it does not get omitted. That's not considered "empty" for an interface.

@rsc rsc closed this as completed Oct 20, 2016
@jnross
Copy link
Author

jnross commented Oct 21, 2016

No, this issue still occurs as originally reported. See my example: https://play.golang.org/p/uw6jvKN-qX

@freeformz
Copy link

@jnross The example you provide is what both @dgryski and @rsc described.

FWIW: I would like an interface of a nil concrete value to also omitempty, but I would be surprised if that change happens.

@golang golang locked and limited conversation to collaborators Oct 21, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

6 participants