Skip to content

encoding/json: unmarshal regression under goexperiment.jsonv2 #74614

Open
@dsnet

Description

@dsnet

Go version

go1.25

Output of go env in your module/workspace:

n/a

What did you do?

Run this code:

type T struct{ calledWith string }

func (t *T) UnmarshalJSON(b []byte) error {
	t.calledWith = string(b)
	return nil
}

func main() {
	var v1, v2 T
	in := []byte("0x")
	err1 := jsonv1.Unmarshal(in, &v1)
	fmt.Println(err1, v1)
	err2 := jsonv1in2.Unmarshal(in, &v2)
	fmt.Println(err2, v2)
}

What did you see happen?

invalid character 'x' after top-level value {}
invalid character 'x' after top-level value {0}

What did you expect to see?

invalid character 'x' after top-level value {}
invalid character 'x' after top-level value {}

Notice that UnmarshalJSON was not called for v1, but is called for v1in2.

It seems that v1in2 eagerly handles any valid JSON prefix, and only reports an error for an invalid suffix after evaluation.
In contrast, v1 validates the entire JSON input up front.

The v1in2 behavior is an artifact of how it prioritizes streaming unmarshal.

It's unclear if this regression matters. I discovered it based on a test failure, but it has no consequential difference in production.

\cc @neild

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.NeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions