{"record":{"id":"5335af57db8221aa","repo":"vitessio/vitess","slug":"duplicate-metric-name-s","errorCode":null,"errorMessage":"duplicate metric name: %s","messagePattern":"duplicate metric name: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/grpcvtctldserver/server.go","lineNumber":2115,"sourceCode":"\tdefer panicHandler(&err)\n\n\tif req.Enable && req.Disable {\n\t\treturn nil, errors.New(\"--enable and --disable are mutually exclusive\")\n\t}\n\n\tif req.MetricName != \"\" && !base.KnownMetricNames.Contains(base.MetricName(req.MetricName)) {\n\t\treturn nil, fmt.Errorf(\"unknown metric name: %s\", req.MetricName)\n\t}\n\n\tif len(req.AppCheckedMetrics) > 0 {\n\t\tspecifiedMetrics := map[base.MetricName]bool{}\n\t\tfor _, metricName := range req.AppCheckedMetrics {\n\t\t\t_, knownMetric, err := base.DisaggregateMetricName(metricName)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid metric name: %s\", metricName)\n\t\t\t}\n\t\t\tif _, ok := specifiedMetrics[knownMetric]; ok {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate metric name: %s\", knownMetric)\n\t\t\t}\n\t\t\tspecifiedMetrics[knownMetric] = true\n\t\t}\n\t}\n\n\tupdate := func(throttlerConfig *topodatapb.ThrottlerConfig) *topodatapb.ThrottlerConfig {\n\t\tif throttlerConfig == nil {\n\t\t\tthrottlerConfig = &topodatapb.ThrottlerConfig{}\n\t\t}\n\t\tif throttlerConfig.ThrottledApps == nil {\n\t\t\tthrottlerConfig.ThrottledApps = make(map[string]*topodatapb.ThrottledAppRule)\n\t\t}\n\t\tif throttlerConfig.AppCheckedMetrics == nil {\n\t\t\tthrottlerConfig.AppCheckedMetrics = make(map[string]*topodatapb.ThrottlerConfig_MetricNames)\n\t\t}\n\t\tif throttlerConfig.MetricThresholds == nil {\n\t\t\tthrottlerConfig.MetricThresholds = make(map[string]float64)\n\t\t}","sourceCodeStart":2097,"sourceCodeEnd":2133,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/grpcvtctldserver/server.go#L2097-L2133","documentation":"UpdateThrottlerConfig rejects AppCheckedMetrics lists containing the same known metric more than once, using a set of already-seen base metric names. Duplicates are ambiguous for the throttler config so the RPC fails fast.","triggerScenarios":"Calling UpdateThrottlerConfig with two entries in req.AppCheckedMetrics that disaggregate to the same known metric, e.g. 'loadaverage' and 'loadaverage.mysql' both present.","commonSituations":"Appending to an existing metrics list in automation without deduplication, or repeating a metric in a CLI comma-list.","solutions":["Deduplicate the AppCheckedMetrics list before calling the RPC (compare disaggregated base metric names).","Keep one canonical form per metric (either bare or fully disaggregated) in your tooling.","Pre-parse entries with base.DisaggregateMetricName in the caller to catch dupes early."],"exampleFix":"// before\n--app-checked-metrics \"loadaverage,loadaverage.mysql\"\n// after\n--app-checked-metrics \"loadaverage.mysql\"","handlingStrategy":"validation","validationCode":"seen := map[base.MetricName]bool{}\nfor _, m := range req.AppCheckedMetrics {\n    known, _, err := base.DisaggregateMetricName(m)\n    if err != nil { return err }\n    if seen[known] { return fmt.Errorf(\"duplicate metric %v\", known) }\n    seen[known] = true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deduplicate by disaggregated base metric name before building the request","Use a set/map when constructing metric lists in automation","Avoid mixing bare and disaggregated forms of the same metric"],"tags":["vitess","throttler","validation","grpc"],"backgroundTag":"invalid-config-value","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}