{"record":{"id":"098ad862c28958e2","repo":"vitessio/vitess","slug":"multitimings-wrong-number-of-values-in-record","errorCode":null,"errorMessage":"MultiTimings: wrong number of values in Record","messagePattern":"MultiTimings: wrong number of values in Record","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/stats/timings.go","lineNumber":242,"sourceCode":"\n// Labels returns descriptions of the parts of each compound category name.\nfunc (mt *MultiTimings) Labels() []string {\n\treturn mt.labels\n}\n\n// Add will add a new value to the named histogram.\nfunc (mt *MultiTimings) Add(names []string, elapsed time.Duration) {\n\tif len(names) != len(mt.labels) {\n\t\tpanic(\"MultiTimings: wrong number of values in Add\")\n\t}\n\tmt.Timings.Add(safeJoinLabels(names, mt.combinedLabels), elapsed)\n}\n\n// Record is a convenience function that records completion\n// timing data based on the provided start time of an event.\nfunc (mt *MultiTimings) Record(names []string, startTime time.Time) {\n\tif len(names) != len(mt.labels) {\n\t\tpanic(\"MultiTimings: wrong number of values in Record\")\n\t}\n\tmt.Timings.Record(safeJoinLabels(names, mt.combinedLabels), startTime)\n}\n\n// Cutoffs returns the cutoffs used in the component histograms.\n// Do not change the returned slice.\nfunc (mt *MultiTimings) Cutoffs() []int64 {\n\treturn bucketCutoffs\n}\n","sourceCodeStart":224,"sourceCodeEnd":252,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/stats/timings.go#L224-L252","documentation":"Like Add, MultiTimings.Record derives the histogram key from the tuple of label values, so it validates that names has exactly one entry per declared label and panics otherwise. Record is the time.Time-based variant used when the caller captured a start time earlier.","triggerScenarios":"Calling mt.Record(names, startTime) where len(names) != len(mt.labels), typically after adding a dimension to the MultiTimings without updating Record call sites.","commonSituations":"Refactoring Timings.Record to MultiTimings.Record while keeping a single-element slice; label count changed at construction (new dimension added) but Record callers not updated; forgetting that Record requires the same arity as Add.","solutions":["Pass exactly one string per declared label: mt.Record([]string{keyspace, table}, start).","Grep all Record call sites when changing the number of labels in NewMultiTimings.","Build the names slice where the dimensions are known, and assert len(names) == len(mt.labels) in tests."],"exampleFix":"// before (labels = [\"Keyspace\", \"Table\"])\nmt.Record([]string{ks}, start) // panics: wrong number of values\n// after\nmt.Record([]string{ks, table}, start)","handlingStrategy":"validation","validationCode":"if len(labelValues) != len(mt.Labels()) {\n    return fmt.Errorf(\"MultiTimings.Record expects %d values, got %d\", len(mt.Labels()), len(labelValues))\n}\nmt.Record(labelValues, start)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep Record and Add call sites using one shared helper that builds the label tuple.","Grep for Record when adding a dimension to a MultiTimings.","Cover both Record and Add in unit tests after label changes."],"tags":["go","stats","panic","timings","arity-mismatch"],"backgroundTag":"length-mismatch","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}