#1744·go-tools

SA9005 does not understand json/v2 custom marshaling

Author: majewskyCreated Sep 8, 2026Updated Sep 8, 2026
Labelsfalse-positiveneeds-triage
  • staticcheck version: honnef.co/go/[email protected] as part of golangci-lint 2.13.2
  • go version: go1.27.0-X:nodwarf5 linux/amd64

In Go 1.27, encoding/json uses encoding/json/v2 under the hood, so the new-style custom marshaling interfaces (json/v2.MarshalerTo and json/v2.UnmarshalerFrom) should be considered equivalent to the old-style interfaces (json.Marshaler and json.Unmarshaler).

Minimal reproducer:

$ cat main.go
package main

import (
	"encoding/json"
	"encoding/json/jsontext"
	json_v2 "encoding/json/v2"
)

type Foo struct {
	x int64
}

var (
	_ json_v2.MarshalerTo     = Foo{}
	_ json_v2.UnmarshalerFrom = &Foo{}
)

func (f Foo) MarshalJSONTo(enc *jsontext.Encoder) error {
	return json_v2.MarshalEncode(enc, f.x)
}

func (f *Foo) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
	return json_v2.UnmarshalDecode(dec, &f.x)
}

func main() {
	foo := Foo{42}
	buf, _ := json.Marshal(foo)
	_ = json.Unmarshal(buf, &foo)
}
$ golangci-lint run
main.go:28:25: SA9005: struct type 'main.Foo' doesn't have any exported fields, nor custom marshaling (staticcheck)
	buf, _ := json.Marshal(foo)
	                       ^
main.go:29:26: SA9005: struct type 'main.Foo' doesn't have any exported fields, nor custom marshaling (staticcheck)
	_ = json.Unmarshal(buf, &foo)
	                        ^
2 issues:
* staticcheck: 2