Go version

go 1.25.0 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='0'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE='on'
GOAMD64='v3'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/deorth/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/deorth/.config/go/env'
GOEXE=''
GOEXPERIMENT='jsonv2,greenteagc'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3589554910=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/deorth/go-jsonrpc/go.mod'
GOMODCACHE='/home/deorth/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/deorth/go'
GOPRIVATE=''
GOPROXY='https://goproxy.cn,direct'
GOROOT='/home/deorth/sdk/go1.25.0'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/deorth/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/deorth/sdk/go1.25.0/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.0'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

try to retrive Marshalers/Unmarshalers from DefaultOptionsV1/DefaultOptionsV2, for example: json.GetOption(json.DefaultOptionsV2(), json.WithMarshalers) playground link

What did you see happen?

panic: interface conversion: interface {} is nil, not *json.typedArshalers[encoding/json/jsontext.Encoder]

What did you expect to see?

no panic

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: andig

*json.typedArshalers

This looks like a typo iself?

Comment From: callthingsoff

Not sure if it's the correct fix, but it avoids the panic

diff --git a/src/encoding/json/v2/options.go b/src/encoding/json/v2/options.go
index 0942d2d307..4cc3ba61ff 100644
--- a/src/encoding/json/v2/options.go
+++ b/src/encoding/json/v2/options.go
@@ -263,12 +263,14 @@ func init() {
                        if !src.Flags.Has(jsonflags.Marshalers) {
                                return (*Marshalers)(nil), false
                        }
-                       return src.Marshalers.(*Marshalers), true
+                       v, ok := src.Marshalers.(*Marshalers)
+                       return v, ok
                case *unmarshalersOption:
                        if !src.Flags.Has(jsonflags.Unmarshalers) {
                                return (*Unmarshalers)(nil), false
                        }
-                       return src.Unmarshalers.(*Unmarshalers), true
+                       v, ok := src.Unmarshalers.(*Unmarshalers)
+                       return v, ok
                default:
                        panic(fmt.Sprintf("unknown option %T", zero))
                }


diff --git a/src/encoding/json/internal/jsonopts/options_test.go b/src/encoding/json/internal/jsonopts/options_test.go
index ebfaf05c83..7e9375faed 100644
--- a/src/encoding/json/internal/jsonopts/options_test.go
+++ b/src/encoding/json/internal/jsonopts/options_test.go
@@ -202,6 +202,15 @@ func TestGet(t *testing.T) {
        }
 }

+func TestGetDefault(t *testing.T) {
+       if v, ok := json.GetOption(json.DefaultOptionsV2(), json.WithMarshalers); v != nil || ok {
+               t.Errorf(`GetOption(..., WithMarshalers) = (%v, %v), want (nil, false)`, v, ok)
+       }
+       if v, ok := json.GetOption(json.DefaultOptionsV2(), json.WithUnmarshalers); v != nil || ok {
+               t.Errorf(`GetOption(..., WithUnmarshalers) = (%v, %v), want (nil, false)`, v, ok)
+       }
+}
+

Comment From: cherrymui

cc @dsnet @neild