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

Comments

Projects
None yet
6 participants
@jnross
Copy link

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

This comment has been minimized.

Copy link
Contributor

commented Aug 17, 2016

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

@jnross

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link
Author

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 label Oct 10, 2016

@rsc

This comment has been minimized.

Copy link
Contributor

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 Oct 20, 2016

@jnross

This comment has been minimized.

Copy link
Author

commented Oct 21, 2016

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

@freeformz

This comment has been minimized.

Copy link
Contributor

commented Oct 21, 2016

@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.
You can’t perform that action at this time.