{"record":{"id":"99838eaa85277751","repo":"golang/go","slug":"parsing-json-v","errorCode":null,"errorMessage":"parsing JSON: %v","messagePattern":"parsing JSON: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/vet/vet.go","lineNumber":383,"sourceCode":"\t\tbase.SetExitStatus(1)\n\t}\n\treturn nil\n}\n\n// printJSONDiagnostics parses JSON (from the tool's stdout) and\n// prints it (to stderr) in \"file:line: message\" form.\n// It also ensures that we exit nonzero if there were diagnostics.\nfunc printJSONDiagnostics(r io.Reader) error {\n\tstdout, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(stdout) > 0 {\n\t\t// unitchecker emits a JSON map of the form:\n\t\t// output maps Package ID -> Analyzer.Name -> (error | []Diagnostic);\n\t\tvar tree jsonTree\n\t\tif err := json.Unmarshal(stdout, &tree); err != nil {\n\t\t\treturn fmt.Errorf(\"parsing JSON: %v\", err)\n\t\t}\n\t\tfor _, units := range tree {\n\t\t\tfor analyzer, msg := range units {\n\t\t\t\tif msg[0] == '[' {\n\t\t\t\t\t// []Diagnostic\n\t\t\t\t\tvar diags []jsonDiagnostic\n\t\t\t\t\tif err := json.Unmarshal([]byte(msg), &diags); err != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"parsing JSON diagnostics: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t\tfor _, diag := range diags {\n\t\t\t\t\t\tbase.SetExitStatus(1)\n\t\t\t\t\t\tprintJSONDiagnostic(analyzer, diag)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// error\n\t\t\t\t\tvar e jsonError\n\t\t\t\t\tif err := json.Unmarshal([]byte(msg), &e); err != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"parsing JSON error: %v\", err)","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/vet/vet.go#L365-L401","documentation":"printJSONDiagnostics could not json.Unmarshal the tool's entire stdout into a jsonTree (map[PackageID]map[AnalyzerName]json.RawMessage). The %v is the json.SyntaxError / UnmarshalTypeError. Fires only with -json analyzers.","triggerScenarios":"An analyzer invoked with -json emitted malformed or non-JSON output, or crashed mid-output printing a partial object, so the top-level unmarshal fails.","commonSituations":"Custom analyzer not implementing the unitchecker JSON contract; analyzer stderr leaking into stdout; tool segfault mid-stream; version skew between cmd/go's expected schema and the analyzer.","solutions":["Run the analyzer standalone with -json and validate its output with jq","Ensure the analyzer uses golang.org/x/tools/go/analysis/unitchecker and emits map[PackageID]map[AnalyzerName]string","Separate stdout (JSON) from stderr (logs)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate analyzer JSON shape before trusting it\nfunc validJSONTree(b []byte) error {\n  var t map[string]map[string]json.RawMessage\n  return json.Unmarshal(b, &t)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build analyzers on golang.org/x/tools/go/analysis/unitchecker for schema compliance","Never write logs to stdout in a -json analyzer; use stderr"],"tags":["go","vet","json","analyzer"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}