Skip to content

Conversation

@rafaeljusto
Copy link
Contributor

@rafaeljusto rafaeljusto commented Jan 2, 2026

Description

When encoding map keys to JSON, it will give priority to the encoding.TextMarshaler implementation, automatically adding quotes to the encoded value. If the encoding already adds the quote,s it will end up with a double-quoted JSON property that may cause issues in the decoding phase.

From https://pkg.go.dev/encoding/json#Marshal:

The map's key type must either be a string, an integer type, or implement encoding.TextMarshaler.

  • keys of any string type are used directly
  • keys that implement encoding.TextMarshaler are marshaled
  • integer keys are converted to strings

Example:

package main

import (
	"encoding/json"
	"fmt"
	"strconv"
)

func main() {
	example1 := map[TypeA]struct{}{
		TypeA(1): struct{}{},
	}
	encoded, err := json.Marshal(example1)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(encoded))

	example2 := map[TypeB]struct{}{
		TypeB(2): struct{}{},
	}
	encoded, err = json.Marshal(example2)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(encoded))

	example3 := map[TypeC]struct{}{
		TypeC(3): struct{}{},
	}
	encoded, err = json.Marshal(example3)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(encoded))
}

type TypeA int

func (t TypeA) MarshalJSON() ([]byte, error) {
	return []byte(`"` + strconv.FormatInt(int64(t), 10) + `"`), nil
}

func (t TypeA) MarshalText() ([]byte, error) {
	return t.MarshalJSON()
}

type TypeB int

func (t TypeB) MarshalJSON() ([]byte, error) {
	return []byte(`"` + strconv.FormatInt(int64(t), 10) + `"`), nil
}

type TypeC int

func (t TypeC) MarshalText() ([]byte, error) {
	return []byte(strconv.FormatInt(int64(t), 10)), nil
}

Output:

{"\"1\"":{}}
{"2":{}}
{"3":{}}

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Testing

  • Tests pass locally (go test -v ./...)
  • Added/updated tests for new functionality

Checklist

  • Code follows project style guidelines
  • Self-reviewed the code
  • Added necessary documentation
  • No new warnings or errors

When encoding map keys to JSON it will give priority to the
`encoding.TextMarshaler` implementation, automatically adding quotes to the
encoded value. If the encoding already add the quotes it will end up with a
double-quoted JSON property that may cause issues in the decoding phase.

From https://pkg.go.dev/encoding/json#Marshal:
> The map's key type must either be a string, an integer type, or implement
> encoding.TextMarshaler.
>
> * keys of any string type are used directly
> * keys that implement encoding.TextMarshaler are marshaled
> * integer keys are converted to strings
@rafaeljusto rafaeljusto requested a review from a team as a code owner January 2, 2026 14:32
@rafaeljusto rafaeljusto merged commit 962fde5 into main Jan 2, 2026
2 checks passed
@rafaeljusto rafaeljusto deleted the fix/marshal-text-quoted branch January 2, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants