{"record":{"id":"f594ead46ce6d84f","repo":"apache/hadoop","slug":"unsupported-add-value-for-metric","errorCode":null,"errorMessage":"Unsupported add(value) for metric {}","messagePattern":"Unsupported add\\(value\\) for metric (.+?)","errorType":"exception","errorClass":"MetricsException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/lib/MetricsRegistry.java","lineNumber":366,"sourceCode":"  synchronized void add(String name, MutableMetric metric) {\n    checkMetricName(name);\n    metricsMap.put(name, metric);\n  }\n\n  /**\n   * Add sample to a stat metric by name.\n   * @param name  of the metric\n   * @param value of the snapshot to add\n   */\n  public synchronized void add(String name, long value) {\n    MutableMetric m = metricsMap.get(name);\n\n    if (m != null) {\n      if (m instanceof MutableStat) {\n        ((MutableStat) m).add(value);\n      }\n      else {\n        throw new MetricsException(\"Unsupported add(value) for metric \"+ name);\n      }\n    }\n    else {\n      metricsMap.put(name, newRate(name)); // default is a rate metric\n      add(name, value);\n    }\n  }\n\n  /**\n   * Set the metrics context tag\n   * @param name of the context\n   * @return the registry itself as a convenience\n   */\n  public MetricsRegistry setContext(String name) {\n    return tag(MsInfo.Context, name, true);\n  }\n\n  /**","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/lib/MetricsRegistry.java#L348-L384","documentation":"MetricsRegistry.add(name, value) is the sampling API for stat metrics: if the name is unknown it lazily creates a MutableRate, but if the name already maps to a metric that is not a MutableStat (MutableGaugeInt/Long, MutableCounterLong, MutableQuantiles) it throws MetricsException('Unsupported add(value) for metric <name>').","triggerScenarios":"Calling registry.add(\"Foo\", 42) when \"Foo\" was registered via newGauge/newCounter/newQuantiles — i.e., pushing samples into a non-stat metric.","commonSituations":"A shared helper that does add(name, elapsed) for arbitrary metrics; reusing a name that another declaration already claimed as a gauge or counter.","solutions":["Hold the MutableStat/MutableRate object and call its add(value) directly","For gauges/counters use their own operations (set, incr) instead of registry.add","Rename the sampled stat so it does not collide with the gauge/counter name"],"exampleFix":"// before\nregistry.newGaugeInt(\"Latency\", \"Latency\", 0);\nregistry.add(\"Latency\", 25);  // throws\n\n// after\nMutableRate latency = registry.newRate(\"Latency\", \"Latency\");\nlatency.add(25);","handlingStrategy":"validation","validationCode":"Map<String, Class<?>> registered = new ConcurrentHashMap<>();\n// record kinds: registered.put(\"Latency\", MutableRate.class);\nClass<?> kind = registered.get(\"Latency\");\nif (kind == null || MutableStat.class.isAssignableFrom(kind)) {\n  registry.add(\"Latency\", value);\n} else {\n  // gauge/counter under that name: use its own API instead\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Hold references to MutableRate/MutableStat objects and call add() on them directly","Reserve registry.add(name, value) for names you know are stats","Never reuse a gauge/counter name for sampled values"],"tags":["metrics2","hadoop","metric-name-collision","type-mismatch"],"backgroundTag":"metric-type-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}