{"record":{"id":"1d967a878e7ccb8f","repo":"apache/iceberg","slug":"invalid-time-unit-s","errorCode":null,"errorMessage":"Invalid time unit: %s","messagePattern":"Invalid time unit: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/metrics/TimerResultParser.java","lineNumber":117,"sourceCode":"    long duration = JsonUtil.getLong(TOTAL_DURATION, timer);\n    return TimerResult.of(unit, toDuration(duration, unit), count);\n  }\n\n  @VisibleForTesting\n  static long fromDuration(Duration duration, TimeUnit unit) {\n    return unit.convert(duration.toNanos(), TimeUnit.NANOSECONDS);\n  }\n\n  @VisibleForTesting\n  static Duration toDuration(long val, TimeUnit unit) {\n    return Duration.of(val, toChronoUnit(unit));\n  }\n\n  private static TimeUnit toTimeUnit(String timeUnit) {\n    try {\n      return TimeUnit.valueOf(timeUnit.toUpperCase(Locale.ROOT));\n    } catch (IllegalArgumentException e) {\n      throw new IllegalArgumentException(String.format(\"Invalid time unit: %s\", timeUnit), e);\n    }\n  }\n\n  private static ChronoUnit toChronoUnit(TimeUnit unit) {\n    switch (unit) {\n      case NANOSECONDS:\n        return ChronoUnit.NANOS;\n      case MICROSECONDS:\n        return ChronoUnit.MICROS;\n      case MILLISECONDS:\n        return ChronoUnit.MILLIS;\n      case SECONDS:\n        return ChronoUnit.SECONDS;\n      case MINUTES:\n        return ChronoUnit.MINUTES;\n      case HOURS:\n        return ChronoUnit.HOURS;\n      case DAYS:","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/metrics/TimerResultParser.java#L99-L135","documentation":"TimerResultParser.toTimeUnit converts the 'timeUnit' JSON field of a timer result into java.util.concurrent.TimeUnit using TimeUnit.valueOf on the upper-cased string. If the string is not a valid TimeUnit constant name, IllegalArgumentException('Invalid time unit: ...') is thrown, indicating malformed metrics JSON.","triggerScenarios":"Parsing a TimerResult JSON (from a metrics report) whose timeUnit field is misspelled, in an unexpected format (e.g. 'nanos', 'ns', 'milli-seconds'), or produced by a different/writer version using non-standard unit names.","commonSituations":"Hand-edited or third-party-generated metrics JSON; reading metrics files produced by another framework; unit strings like 'NANOSECOND' (singular) or lowercase abbreviations.","solutions":["Use standard TimeUnit constant names in the JSON: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS","Fix the producer of the metrics JSON to emit TimeUnit.valueOf-compatible names","Validate/sanitize the timeUnit string before parsing, mapping abbreviations ('ns' -> 'NANOSECONDS') yourself","Catch IllegalArgumentException when parsing untrusted metrics files and skip or remap the offending timer"],"exampleFix":"// before\nString unit = \"ns\"; // fails\n// after\nString unit = switch (raw) {\n  case \"ns\" -> \"NANOSECONDS\";\n  case \"ms\" -> \"MILLISECONDS\";\n  default -> raw.toUpperCase(Locale.ROOT);\n};","handlingStrategy":"validation","validationCode":"boolean validTimeUnit(String s) {\n  try { TimeUnit.valueOf(s.toUpperCase(Locale.ROOT)); return true; }\n  catch (IllegalArgumentException | NullPointerException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  TimerResultParser.fromJson(json);\n} catch (IllegalArgumentException e) {\n  LOG.warn(\"Skipping malformed timer: {}\", e.getMessage());\n}","preventionTips":["Emit standard TimeUnit constant names (NANOSECONDS, MILLISECONDS, ...) in metrics JSON","Validate metrics files from third-party producers before parsing","Map abbreviations (ns/ms) to TimeUnit names at ingestion"],"tags":["metrics","parsing","timeunit","invalid-value"],"backgroundTag":"invalid-enum-value","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}