MarshalJSON error , invalid character "g" after top-level

11,775

34gj is not a valid JSON and hence not a valid string representation of your ID. You probably want to wrap this with double quotation mark to indicate this is a string, i.e. returning "34gj".

Try:

func (id ID) MarshalJSON() ([]byte, error) {
    e, _ := HashIDs.Encode([]int{int(id)})
    fmt.Println(e) /// 34gj
    return []byte(`"` + e + `"`), nil
}

http://play.golang.org/p/0ESimzPbAx

Instead of doing it by hand you can also call marshaller for the string, by simply replacing your return with return json.Marshal(e).

My guess would be that invalid character 'g' in your error is due to initial part of the value is being treated as a number and then unexpected character occurs.

Share:
11,775
Emad Ghasemi
Author by

Emad Ghasemi

Updated on June 05, 2022

Comments

  • Emad Ghasemi
    Emad Ghasemi almost 2 years

    I made a custom type for my IDs:

    type ID uint
    
    func (id ID) MarshalJSON() ([]byte, error) {
        e, _ := HashIDs.Encode([]int{int(id)})
        fmt.Println(e) /// 34gj
        return []byte(e), nil
    }
    
    func (id *ID) Scan(value interface{}) error {
        *id = ID(value.(int64))
        return nil
    }
    

    I use the HashIDs package to encode my ids so that user wont be able to read them on client side. But I'm getting this error:

    json: error calling MarshalJSON for type types.ID: invalid character 'g' after top-level value

  • Emad Ghasemi
    Emad Ghasemi almost 9 years
    Yes, it might... I had tought the marshaller wrap it it self in " " but don't know why this happend... anyway this solved it, thanks
  • Emad Ghasemi
    Emad Ghasemi almost 9 years
    I hope there's a better explanation for this behavior
  • tomasz
    tomasz almost 9 years
    Emad, it can't wrap it for you with " automatically as by implementing marshaller you're supposed to provide a valid raw JSON. So you can, for example, return {"id": "abc"} (not a string!). Obviously wrapping it with quotes would be wrong. You can always use return json.Marshal(e) in your code to provide a valid string representation without worrying about quotes (added this comment to my answer).