We had experience where the type of a field changes base on certain conditions. We think this is really bad but we have to support it somehow. Here’s how.

You’ll have to specify the field type as interface.

type P struct {
	T interface{} `json:"t"`

After that you’ll need to use switch to determine the type. In our case, we needed it as int.

var i int

var p P

s := `{"t": "3460"}`
// should also work with
// s := `{"t": 3460}`
if err := json.NewDecoder(r.Body).Decode(strings.NewReader(s)); err != nil {

switch t := p.(type) {
case float64:
	i := int(t)
case string:
	var err error
	if i, err = strconv.Atoi(t); err != nil {
		return nil, fmt.Errorf("t is not a number: %#v", err)
	fmt.Errorf("t is of invalid type: %#v", t)

Simple as that. Thanks again to my colleague Harmen for this solution.