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: Unmarshal (but not Decode) panics when UnmarshalJSON returns an error #4784

bradfitz opened this issue Feb 10, 2013 · 3 comments


Copy link

Unmarshal (but not Decode) panics instead of returning an error when a type's
UnmarshalJSON returns an error.

For example, add this to decode_test.go:

// Time3339 is a time.Time which encodes to and from JSON                               
// as an RFC 3339 time in UTC.                                                          
type Time3339 time.Time

func (t *Time3339) UnmarshalJSON(b []byte) error {
        if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
        return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time")
        tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1]))
    if err != nil {
                return err
    *t = Time3339(tm)
        return nil

func TestUnmarshalJSONLiteralError(t *testing.T) {
        var t3 Time3339
        err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3)
        if err == nil {
                t.Fatalf("expected error; got time %v", time.Time(t3))
    if !strings.Contains(err.Error(), "range") {
                t.Errorf("got err = %v; want out of range error", err)

It then panics with:

--- PASS: TestUnmarshalJSONLiteralError (0.00 seconds)
panic: parsing time "0000-00-00T00:00:00Z": month out of range [recovered]
    panic: parsing time "0000-00-00T00:00:00Z": month out of range

goroutine 22 [running]:
testing.func·004(0x10384fa8, 0x10384100)
    /Users/bradfitz/go/src/pkg/testing/testing.go:309 +0xb3
encoding/json.(*decodeState).error(0xc2000ff800, 0xc200383c30, 0xc200181460, 0x16)
    /Users/bradfitz/go/src/pkg/encoding/json/decode.go:203 +0x47
encoding/json.(*decodeState).literalStore(0xc2000ff800, 0xc2000fe660, 0x16, 0x16,
0x18ea08, ...)
    /Users/bradfitz/go/src/pkg/encoding/json/decode.go:621 +0x286
encoding/json.Unmarshal(0xc2000fe660, 0x16, 0x16, 0x177d98, 0xc2000fe640, ...)
    /Users/bradfitz/go/src/pkg/encoding/json/decode.go:82 +0x266
encoding/json.TestUnmarshalJSONLiteralError(0xc2002d0750, 0x1dd35e08)
    /Users/bradfitz/go/src/pkg/encoding/json/decode_test.go:1136 +0xbd
testing.tRunner(0xc2002d0750, 0x2b91a8, 0x0, 0x0)
    /Users/bradfitz/go/src/pkg/testing/testing.go:314 +0x6c
created by testing.RunTests
    /Users/bradfitz/go/src/pkg/testing/testing.go:429 +0x875

goroutine 1 [chan receive]:
testing.RunTests(0x2000, 0x2b8fe0, 0x29, 0x29, 0x1, ...)
    /Users/bradfitz/go/src/pkg/testing/testing.go:430 +0x898
testing.Main(0x2000, 0x2b8fe0, 0x29, 0x29, 0x2b6350, ...)
    /Users/bradfitz/go/src/pkg/testing/testing.go:326 +0x8a
    encoding/json/_test/_testmain.go:149 +0x9a
exit status 2
FAIL    encoding/json   0.101s
Copy link

rsc commented Feb 14, 2013

Comment 1:

Caused by the optimization introduced in:
changeset:   15532:de89928ea00f
user:        Rick Arnold <>
date:        Wed Jan 30 17:53:48 2013 -0800
summary:     encoding/json: improve performance of Unmarshal on primitive types
That's the second attempt and the second time it broke Unmarshal. 
We should roll it back and stop trying.

Copy link

rsc commented Feb 14, 2013

Comment 2:

Copy link

rsc commented Feb 14, 2013

Comment 3:

This issue was closed by revision d340a89.

Status changed to Fixed.

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015
@rsc rsc removed the go1.1 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet

No branches or pull requests

3 participants