Search code examples
gomarshallingpanic

Go json Marshaller panics with "call of reflect.Value.Int on zero Value"


I am trying to unmarshal some data in a complex struct with multi-level nesting (thus, not copying the struct here). However, when the code went live, we started getting the following panic in rare occasions (difficult to quantify but perhaps 1 in 1000 cases).

Below is the stack trace of the issue:

panic: reflect: call of reflect.Value.Int on zero Value [recovered]
        panic: reflect: call of reflect.Value.Int on zero Value

    goroutine 568428 [running]:
    encoding/json.(*encodeState).marshal.func1(0xc0081d5c70)
            /usr/local/go/src/encoding/json/encode.go:305 +0x9a
    panic(0x13968c0, 0xc005c2f540)
            /usr/local/go/src/runtime/panic.go:679 +0x1b2
    reflect.Value.Int(...)
            /usr/local/go/src/reflect/value.go:986
    encoding/json.intEncoder(0xc0074b5dc0, 0x0, 0x0, 0x0, 0xc0038b0100)
            /usr/local/go/src/encoding/json/encode.go:522 +0x1d4
    encoding/json.mapEncoder.encode(0x1608760, 0xc0074b5dc0, 0x1385c20, 0xc00119f5e0, 0x195, 0x100)
            /usr/local/go/src/encoding/json/encode.go:706 +0x351
    encoding/json.structEncoder.encode(0xc0002ce600, 0x19, 0x21, 0xc00027ede0, 0xc0074b5dc0, 0x156c820, 0xc00119f510, 0x199, 0x520100)
            /usr/local/go/src/encoding/json/encode.go:664 +0x306
    encoding/json.ptrEncoder.encode(0xc00027ee10, 0xc0074b5dc0, 0x1397e80, 0xc00119f510, 0x16, 0x1390100)
            /usr/local/go/src/encoding/json/encode.go:810 +0xb1
    encoding/json.(*encodeState).reflectValue(0xc0074b5dc0, 0x1397e80, 0xc00119f510, 0x16, 0x100)
            /usr/local/go/src/encoding/json/encode.go:337 +0x82
    encoding/json.(*encodeState).marshal(0xc0074b5dc0, 0x1397e80, 0xc00119f510, 0xc003da0100, 0x0, 0x0)
            /usr/local/go/src/encoding/json/encode.go:309 +0x10b
    encoding/json.Marshal(0x1397e80, 0xc00119f510, 0x40be53, 0x13c4160, 0x1397e80, 0x1, 0x7fa9d5d348b0)
            /usr/local/go/src/encoding/json/encode.go:161 +0x52
    reingames.com/rm/user.(*userCore).MarshalBinary(0xc00119f510, 0x1397e80, 0xc00119f510, 0x7fa9d5d348b0, 0xc00119f510, 0x1)
            /home/shivam/goprojects/rmgs/go/user/profile.go:180 +0x37

I have no clue where to start debugging this. Has anyone experienced something similar? Quick question - could a race condition (marshalling a pointer while it is being updated) cause this panic?

Thanks


Solution

  • One way to start debugging is : catch the panic with a recover() instruction, and log information about the context of the error.

    This wouldn't catch a race condition "in the act", but it would certainly help you understand more things about your error (does it occur always on the same elements ? is the element still in a valid state ? etc ...)