{"record":{"id":"f9e32a30a9405fbf","repo":"JuliusBrussee/caveman","slug":"proposalrun-detail-is-not-valid-json-w","errorCode":null,"errorMessage":"proposalrun: detail is not valid JSON: %w","messagePattern":"proposalrun: detail is not valid JSON: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/proposalrun/proposalrun.go","lineNumber":64,"sourceCode":"//\n// Numbers are decoded with Decoder.UseNumber and normalized by exact decimal\n// coefficient/exponent arithmetic, so they never round through float64. The\n// canonical form is a plain decimal with insignificant zeroes removed; zero is\n// always \"0\". Thus storage-equivalent spellings (for example 1, 1.0, and 1e0)\n// hash identically, while adjacent arbitrary-precision integers remain\n// distinct. The bounds mirror PostgreSQL's numeric-backed jsonb limits and\n// reject values that could not be persisted there before allocating output.\n// The decoder enforces the JSON number grammar (including rejecting NaN/Inf),\n// and a second decode below rejects any trailing value or non-whitespace data.\nfunc CanonicalDetail(detail json.RawMessage) ([]byte, error) {\n\tif len(detail) == 0 {\n\t\treturn []byte(\"{}\"), nil\n\t}\n\tvar v any\n\tdec := json.NewDecoder(bytes.NewReader(detail))\n\tdec.UseNumber()\n\tif err := dec.Decode(&v); err != nil {\n\t\treturn nil, fmt.Errorf(\"proposalrun: detail is not valid JSON: %w\", err)\n\t}\n\tvar trailing any\n\tif err := dec.Decode(&trailing); err != io.EOF {\n\t\tif err == nil {\n\t\t\treturn nil, fmt.Errorf(\"proposalrun: detail contains trailing JSON\")\n\t\t}\n\t\treturn nil, fmt.Errorf(\"proposalrun: detail contains trailing data: %w\", err)\n\t}\n\tv, err := canonicalizeJSONValue(v)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"proposalrun: canonicalize detail: %w\", err)\n\t}\n\tout, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"proposalrun: marshal canonical detail: %w\", err)\n\t}\n\treturn out, nil\n}","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/shared/platform/proposalrun/proposalrun.go#L46-L82","documentation":"Error \"proposalrun: detail is not valid JSON: %w\" thrown in JuliusBrussee/caveman.","triggerScenarios":"Thrown at shared/platform/proposalrun/proposalrun.go:64 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Store valid JSON in the proposal run detail."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}