{"record":{"id":"c149f52a11d0953c","repo":"apache/iceberg","slug":"counter-for-type-s-is-not-supported-c149f5","errorCode":null,"errorMessage":"Counter for type %s is not supported","messagePattern":"Counter for type (.+?) is not supported","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/metrics/MetricsContext.java","lineNumber":182,"sourceCode":"      @Override\n      public Timer timer(String name, TimeUnit unit) {\n        return Timer.NOOP;\n      }\n\n      @Override\n      @SuppressWarnings(\"unchecked\")\n      public <T extends Number> Counter<T> counter(String name, Class<T> type, Unit unit) {\n        if (Integer.class.equals(type)) {\n          return (Counter<T>)\n              ((DefaultCounter) org.apache.iceberg.metrics.DefaultCounter.NOOP).asIntCounter();\n        }\n\n        if (Long.class.equals(type)) {\n          return (Counter<T>)\n              ((DefaultCounter) org.apache.iceberg.metrics.DefaultCounter.NOOP).asLongCounter();\n        }\n\n        throw new IllegalArgumentException(\n            String.format(\"Counter for type %s is not supported\", type.getName()));\n      }\n\n      @Override\n      public org.apache.iceberg.metrics.Counter counter(String name, Unit unit) {\n        return org.apache.iceberg.metrics.DefaultCounter.NOOP;\n      }\n    };\n  }\n}\n","sourceCodeStart":164,"sourceCodeEnd":193,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/metrics/MetricsContext.java#L164-L193","documentation":"This is the logging/no-op MetricsContext inside MetricsContext: counter(name, type) returns DefaultCounter.NOOP for Integer and Long, but any other Number type throws IllegalArgumentException('Counter for type %s is not supported'). Even in a no-op context the counter type must still be Integer or Long.","triggerScenarios":"Calling counter(name, Double.class, unit) (or any non-int/long type) on the no-op/logging context returned by MetricsContext.unsupportedCounter-style defaults.","commonSituations":"Assuming the no-op context accepts any metric type since it discards data anyway; refactoring counter types to Double without checking the context.","solutions":["Use Integer.class or Long.class as the counter type","Use DefaultMetricsContext if you need real values or other types via different mechanisms","Catch IllegalArgumentException and skip the metric for unsupported types"],"exampleFix":"// before\nCounter<Double> c = noopCtx.counter(\"x\", Double.class, Unit.COUNT); // throws\n// after\nCounter<Long> c = noopCtx.counter(\"x\", Long.class, Unit.COUNT); // NOOP counter","handlingStrategy":"validation","validationCode":"if (type != Integer.class && type != Long.class) type = Long.class;","typeGuard":"boolean ok(Class<?> t) { return t == Integer.class || t == Long.class; }","tryCatchPattern":"try { noopCtx.counter(...) } catch (IllegalArgumentException e) { use Long.class }","preventionTips":["Only Integer/Long in no-op context too","Default to Long.class"],"tags":["java","metrics","noop","illegal-argument"],"backgroundTag":"invalid-argument-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}