Skip to content

How to parse JSON string with trailing commas in Golang

A Standard JSON string doesn't allow trailing commas after the final element of arrays and objects.

But a extention of JSON called JWCC supports commas and event comments.

So, the following string is not a valid JSON string, but is a valid JWCC string.

json
{
    "objects": [
        {
            "name": "foo"
        },
    ]
}
{
    "objects": [
        {
            "name": "foo"
        },
    ]
}

So when we try to parse this JSON string to a Go struct using the standard JSON parser, we will get an error message saying "invalid character ']' looking for beginning of value".

The parsing code is as follows:

go
package main

import (
	"encoding/json"
	"fmt"
)

type Data struct {
	Objects []map[string]string `json:"objects"`
}

var jsonString = `
{
    "objects": [
        {
            "name": "foo"
        },
    ]
}
`

func main() {
	var data Data
	if err := json.Unmarshal([]byte(jsonString), &data); err != nil {
		fmt.Println(err)
	}
}
package main

import (
	"encoding/json"
	"fmt"
)

type Data struct {
	Objects []map[string]string `json:"objects"`
}

var jsonString = `
{
    "objects": [
        {
            "name": "foo"
        },
    ]
}
`

func main() {
	var data Data
	if err := json.Unmarshal([]byte(jsonString), &data); err != nil {
		fmt.Println(err)
	}
}

To correctly parse JWCC string, we can first use the hujson library to standardize the JSON string. Then, we can use a standard JSON to parse the standardized JSON string correctly.

The parsing code is as follows:

go
package main

import (
	"encoding/json"
	"fmt"

	"github.com/tailscale/hujson"
)

type Data struct {
	Objects []map[string]string `json:"objects"`
}

var jsonString = `
{
    "objects": [
        {
            "name": "foo"
        },
    ]
}
`

func main() {
	var data Data

	b, err := hujson.Standardize([]byte(jsonString))
	if err != nil {
		fmt.Println(err)
		return
	}

	if err := json.Unmarshal(b, &data); err != nil {
		fmt.Println(err)
	}
	fmt.Print(data)
}
package main

import (
	"encoding/json"
	"fmt"

	"github.com/tailscale/hujson"
)

type Data struct {
	Objects []map[string]string `json:"objects"`
}

var jsonString = `
{
    "objects": [
        {
            "name": "foo"
        },
    ]
}
`

func main() {
	var data Data

	b, err := hujson.Standardize([]byte(jsonString))
	if err != nil {
		fmt.Println(err)
		return
	}

	if err := json.Unmarshal(b, &data); err != nil {
		fmt.Println(err)
	}
	fmt.Print(data)
}

References