Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"invalid character '\x00' after top-level value"

Tags:

json

go

I am getting this error while unmarshalling json in a for loop. The first time through the loop is unmarshalling fine but on the next iteration I am getting this error.

I am new to golang and this error message is not clear. Can someone please explain in what cases this error occurs and how I am supposed to avoid it.

like image 930
Oliver.Oakley Avatar asked Aug 07 '14 16:08

Oliver.Oakley


2 Answers

Looking at the source code of encoding/json/scanner.go

// stateEndTop is the state after finishing the top-level value,
// such as after reading `{}` or `[1,2,3]`.
// Only space characters should be seen now.
func stateEndTop(s *scanner, c int) int {
    if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
        // Complain about non-space byte on next call.
        s.error(c, "after top-level value")
    }
    return scanEnd
}

So check how your JSON string ends.

For example, in this thread, to illustrate a potential issue:

ReadFromUDP can return a packet of any size, from 1 to 2000 bytes, you need to reslice your buffer using the number of bytes actually read.

json.Unmarshal(buf[:n], &msg)

Same in this thread:

request := make([]byte, 1024)
read_len, err := conn.Read(request)
request_right := request[:read_len]
j := new(Json)
err := j.UnmarshalJSON(request) // not working

if read_len < len(request) then request will contain extra "\x00" at the end and that's why UnmarshalJSON(request) won't work.

like image 128
VonC Avatar answered Oct 21 '22 09:10

VonC


Thank you for answering my question.

This error came due to incorrect json before that there is little more story to this,

I have a field detail of type json.RawMessage I have SELECT query where I am trying to read json from the table and scan to detail and appending it to the struct.

After for loop ends when I look at detail JSON it got same record multiple times with and without end braces. After giving it so much thinking I figured casting detail with byte helped.

Eg: instead of just rows.Scan(&detail) try this: rows.Scan((*[]byte)(&detail)) solved the above problem

like image 29
Oliver.Oakley Avatar answered Oct 21 '22 09:10

Oliver.Oakley