{"record":{"id":"632433e0d10b47f6","repo":"cockroachdb/cockroach","slug":"failed-parsing-datum-string-as","errorCode":null,"errorMessage":"failed parsing datum string as ","messagePattern":"failed parsing datum string as ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cli/statement_bundle.go","lineNumber":435,"sourceCode":"\t\t\tbuckets := stat[\"histo_buckets\"].([]interface{})\n\t\t\t// addedNonExistent tracks whether we included at least one\n\t\t\t// \"previous\" datum which - according to the histograms - is not\n\t\t\t// present in the table.\n\t\t\tvar addedNonExistent bool\n\t\t\tvar maxUpperBound tree.Datum\n\t\t\tfor _, b := range buckets {\n\t\t\t\tbucket := b.(map[string]interface{})\n\t\t\t\tnumRange := bucket[\"num_range\"].(float64)\n\t\t\t\tkey := bucketKey{\n\t\t\t\t\tNumEq:         bucket[\"num_eq\"].(float64),\n\t\t\t\t\tNumRange:      numRange,\n\t\t\t\t\tDistinctRange: bucket[\"distinct_range\"].(float64),\n\t\t\t\t}\n\t\t\t\tupperBound := bucket[\"upper_bound\"].(string)\n\t\t\t\tbucketMap[key] = []string{upperBound}\n\t\t\t\tdatum, err := rowenc.ParseDatumStringAs(ctx, colType, upperBound, &evalCtx, nil /* semaCtx */)\n\t\t\t\tif err != nil {\n\t\t\t\t\tpanic(\"failed parsing datum string as \" + colType.String() + \" \" + err.Error())\n\t\t\t\t}\n\t\t\t\tif maxUpperBound == nil {\n\t\t\t\t\tmaxUpperBound = datum\n\t\t\t\t} else if cmp, err := maxUpperBound.Compare(ctx, &evalCtx, datum); err != nil {\n\t\t\t\t\tpanic(err)\n\t\t\t\t} else if cmp < 0 {\n\t\t\t\t\tmaxUpperBound = datum\n\t\t\t\t}\n\t\t\t\t// If we have any datums within the bucket (i.e. not equal to\n\t\t\t\t// the upper bound), we always attempt to add a \"previous\" to\n\t\t\t\t// the upper bound datum.\n\t\t\t\taddPrevious := numRange > 0\n\t\t\t\tif numRange == 0 && !addedNonExistent {\n\t\t\t\t\t// If our bucket says that there are no values present in\n\t\t\t\t\t// the table between the current upper bound and the upper\n\t\t\t\t\t// bound of the previous histogram bucket, then we only\n\t\t\t\t\t// attempt to add the \"previous\" non-existent datum if we\n\t\t\t\t\t// haven't done so already (this is to avoid the redundant","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/cockroachdb/cockroach/blob/8812064a015d2faf99d3fc7e15880f94042954b0/pkg/cli/statement_bundle.go#L417-L453","documentation":"While consuming statistics.json from a statement bundle (placeholder machinery used by statement-bundle editing), each histogram bucket's upper_bound string is parsed with rowenc.ParseDatumStringAs against the type taken from histo_col_type. A parse failure panics with 'failed parsing datum string as <colType> <err>', aborting the whole command — the error is not returned gracefully.","triggerScenarios":"An upper_bound whose string encoding doesn't round-trip through histo_col_type: statistics produced by a different CockroachDB version with changed datum formatting, hand-edited or foreign statistics.json files, or a type whose string form ParseDatumStringAs rejects.","commonSituations":"Applying/editing a statement bundle captured on an older or newer cluster; statistics.json copied between clusters; user-modified histogram buckets; rarely, encoding changes for exotic types (arrays, certain collations) across versions.","solutions":["Regenerate the statement bundle on the cluster that ran the query, then retry","Open statistics.json and compare histo_col_type with the actual upper_bound strings for the failing column (the panic message names the type and underlying error)","Process the bundle with the cockroach binary version matching the cluster that produced it","If the JSON is valid and from a supported version, report a bug — parsing should error, not panic"],"exampleFix":"// before (statement_bundle.go)\nif err != nil {\n  panic('failed parsing datum string as ' + colType.String() + ' ' + err.Error())\n}\n\n// after: propagate a descriptive error instead of panicking\nif err != nil {\n  return nil, nil, errors.Wrapf(err, 'parsing upper_bound %q for column %s as %s', upperBound, fqColName, colType.String())\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Process statement bundles with the binary version that produced them","Never hand-edit histogram upper_bound values in statistics.json","Regenerate bundles on-cluster instead of reusing old statistics.json across versions"],"tags":["cli","statement-bundle","statistics","histogram","go"],"backgroundTag":null,"analyzedSha":"8812064a015d2faf99d3fc7e15880f94042954b0","analyzedAt":"2026-08-15T16:34:17.351Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}