{"record":{"id":"3406a2a4c1fe99bc","repo":"apache/iceberg","slug":"invalid-metrics-mode","errorCode":null,"errorMessage":"Invalid metrics mode: ","messagePattern":"Invalid metrics mode: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/MetricsModes.java","lineNumber":54,"sourceCode":"\n  private MetricsModes() {}\n\n  public static MetricsMode fromString(String mode) {\n    if (\"none\".equalsIgnoreCase(mode)) {\n      return None.get();\n    } else if (\"counts\".equalsIgnoreCase(mode)) {\n      return Counts.get();\n    } else if (\"full\".equalsIgnoreCase(mode)) {\n      return Full.get();\n    }\n\n    Matcher truncateMatcher = TRUNCATE.matcher(mode.toLowerCase(Locale.ROOT));\n    if (truncateMatcher.matches()) {\n      int length = Integer.parseInt(truncateMatcher.group(1));\n      return Truncate.withLength(length);\n    }\n\n    throw new IllegalArgumentException(\"Invalid metrics mode: \" + mode);\n  }\n\n  /**\n   * A metrics calculation mode.\n   *\n   * <p>Implementations must be immutable.\n   */\n  public interface MetricsMode extends Serializable {\n    default boolean hasBounds() {\n      throw new UnsupportedOperationException(\n          \"Unexpected implementation of MetricsMode without hasBounds\");\n    }\n  }\n\n  /**\n   * Under this mode, value_counts, null_value_counts, nan_value_counts, lower_bounds, upper_bounds\n   * are not persisted.\n   */","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/MetricsModes.java#L36-L72","documentation":"MetricsModes.fromString parses a table property value (write.metadata.metrics.default/column, e.g. 'none', 'all', 'counts', 'truncate(L)') into a MetricsModes instance and throws IllegalArgumentException when the string matches none of the known patterns. The value is either misspelled or uses an unsupported truncate syntax.","triggerScenarios":"Setting table property 'write.metadata.metrics.default' or a per-column metric property to a value like 'trunc(16)', 'Truncate', 'truncated(10)', or any empty/garbage string that is not none/all/counts/truncate(<n>).","commonSituations":"Typos in table properties via SQL ('ALTER TABLE ... SET TBLPROPERTIES'), Spark/Flink config, or catalog configuration files; truncating with invalid syntax like 'truncate()' or non-integer length.","solutions":["Use one of the valid modes exactly: 'none', 'all', 'counts', or 'truncate(N)' where N is a positive integer.","Check for typos/extra whitespace in the property value; parsing is case-insensitive but spelling must be exact.","If truncating, ensure the format is truncate(16) — no spaces, integer length, spelled out fully."],"exampleFix":"// before\ntable.updateProperties().set(\"write.metadata.metrics.default\", \"trunc(16)\");\n// after\ntable.updateProperties().set(\"write.metadata.metrics.default\", \"truncate(16)\");","handlingStrategy":"validation","validationCode":"String mode = props.get(\"write.metadata.metrics.default\");\nif (mode != null && !mode.matches(\"(?i)none|all|counts|truncate\\\\(\\\\d+\\\\)\")) {\n  throw new IllegalArgumentException(\"Invalid metrics mode: \" + mode);\n}","typeGuard":null,"tryCatchPattern":"try {\n  MetricsModes.fromString(mode);\n} catch (IllegalArgumentException e) {\n  MetricsModes metricsMode = MetricsModes.None.get(); // safe default\n}","preventionTips":["Only use the documented values: none, all, counts, truncate(N).","Validate table properties on write (e.g. in SQL or CI) rather than at scan time.","Remember parsing is case-insensitive but whitespace-sensitive — trim inputs."],"tags":["invalid-config-value","metrics-mode","table-properties","java"],"backgroundTag":"invalid-config-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"}