Skip to content

encoding/json: Marshal silently ignores custom implementations on pass by value #30351

@mcandre

Description

@mcandre

What version of Go are you using (go version)?

$ go version
go version go1.11 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/tkmamhf/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/tkmamhf/go"
GOPROXY=""
GORACE=""
GOROOT="/Users/tkmamhf/.gvm/gos/go1.11"
GOTMPDIR=""
GOTOOLDIR="/Users/tkmamhf/.gvm/gos/go1.11/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/y6/dbk1vvs179nbpfv38j__10b5rsnf87/T/go-build193800130=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Carefully implemented json.Marshaler and json.Unmarshaler interfaces, and passed my struct directly to json.Marshal().

What did you expect to see?

The resulting JSON byte array uses my custom json.Marshaler interface method.

What did you see instead?

The resulting JSON byte array ignores my custom json.Marshaler interface method, instead presenting the keys and values of the plain Go struct declaration. This causes downstream breakages, as my custom JSON marshaling is needed to offset some issues with the data I happen to be handling.

Workaround

As a workaround, I am making sure that I pass a reference (&) of my object to the json.Marshal() method. This is quite dangerous, as it is a really easy mistake to make, across a large codebase. And currently no way to validate this with the Go type system on the existing API. With other Go API calls, I at least get an annoying compile about needing a receiver pointer.

In the future, can we improve the json API to prevent this from happening?

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeWaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions