{"record":{"id":"e5bc7ddefc734026","repo":"apache/hadoop","slug":"no-valid-metric-annotation-found","errorCode":null,"errorMessage":"No valid @Metric annotation found.","messagePattern":"No valid @Metric annotation found\\.","errorType":"exception","errorClass":"MetricsException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/lib/MetricsSourceBuilder.java","lineNumber":84,"sourceCode":"    registry = initRegistry(source);\n\n    for (Field field : ReflectionUtils.getDeclaredFieldsIncludingInherited(cls)) {\n      add(source, field);\n    }\n    for (Method method : ReflectionUtils.getDeclaredMethodsIncludingInherited(cls)) {\n      add(source, method);\n    }\n  }\n\n  public MetricsSource build() {\n    if (source instanceof MetricsSource) {\n      if (hasAtMetric && !hasRegistry) {\n        throw new MetricsException(\"Hybrid metrics: registry required.\");\n      }\n      return (MetricsSource) source;\n    }\n    else if (!hasAtMetric) {\n      throw new MetricsException(\"No valid @Metric annotation found.\");\n    }\n    return new MetricsSource() {\n      @Override\n      public void getMetrics(MetricsCollector builder, boolean all) {\n        registry.snapshot(builder.addRecord(registry.info()), all);\n      }\n    };\n  }\n\n  public MetricsInfo info() {\n    return info;\n  }\n\n  private MetricsRegistry initRegistry(Object source) {\n    Class<?> cls = source.getClass();\n    MetricsRegistry r = null;\n    // Get the registry if it already exists.\n    for (Field field : ReflectionUtils.getDeclaredFieldsIncludingInherited(cls)) {","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/metrics2/lib/MetricsSourceBuilder.java#L66-L102","documentation":"MetricsSourceBuilder.build() throws MetricsException('No valid @Metric annotation found.') when the object neither implements MetricsSource nor produced any usable @Metric member during the scan — the builder has nothing to build a metrics source from (hasAtMetric stayed false).","triggerScenarios":"Passing a plain class with no @Metric-annotated fields or methods; or a class whose @Metric members were all rejected earlier in the scan (unsupported types), so none of them set hasAtMetric.","commonSituations":"Refactors that removed annotations; @Metric imported from the wrong package; annotations only on static members that the scan skips or fails to wire.","solutions":["Annotate instance fields or methods with org.apache.hadoop.metrics2.annotation.Metric","Or implement MetricsSource.getMetrics for a fully custom source","Verify the annotated members are instance members of supported types (they must be wireable)"],"exampleFix":"// before\nclass MyMetrics { public long getSize() { return size; } }\nnew MetricsSourceBuilder(new MyMetrics(), \"MyMetrics\").build();  // throws\n\n// after\nclass MyMetrics {\n  @Metric public MutableGaugeLong size;\n}\nnew MetricsSourceBuilder(new MyMetrics(), \"MyMetrics\").build();","handlingStrategy":"validation","validationCode":"static boolean hasValidMetricAnnotation(Class<?> cls) {\n  boolean onFields = Arrays.stream(cls.getDeclaredFields())\n      .anyMatch(f -> f.isAnnotationPresent(Metric.class));\n  boolean onMethods = Arrays.stream(cls.getDeclaredMethods())\n      .anyMatch(m -> m.isAnnotationPresent(Metric.class));\n  return onFields || onMethods || MetricsSource.class.isAssignableFrom(cls);\n}\nif (!hasValidMetricAnnotation(cls)) throw new IllegalArgumentException(cls + \" has no @Metric members\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure org.apache.hadoop.metrics2.annotation.Metric is the imported annotation","Annotate at least one instance field or method, or implement MetricsSource","Cover metrics classes with a unit test that builds them via MetricsSourceBuilder"],"tags":["metrics2","hadoop","annotation","builder"],"backgroundTag":"missing-metric-annotation","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}