{"record":{"id":"8c7195435cd22617","repo":"apache/beam","slug":"compression-factor-should-be-greater-than-0","errorCode":null,"errorMessage":"Compression factor should be greater than 0.","messagePattern":"Compression factor should be greater than 0\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sketching/src/main/java/org/apache/beam/sdk/extensions/sketching/TDigestQuantiles.java","lineNumber":265,"sourceCode":"\n    private TDigestQuantilesFn(double compression) {\n      this.compression = compression;\n    }\n\n    /**\n     * Returns {@link TDigestQuantilesFn} combiner with the given compression factor.\n     *\n     * <p>Keep in mind that a compression factor {@code cf} of c guarantees a relative error less\n     * than 3/c at mid quantiles. <br>\n     * The accuracy will always be significantly less than 1% at extreme quantiles.\n     *\n     * @param compression the bound value for centroid and digest sizes.\n     */\n    public static TDigestQuantilesFn create(double compression) {\n      if (compression > 0) {\n        return new TDigestQuantilesFn(compression);\n      }\n      throw new IllegalArgumentException(\"Compression factor should be greater than 0.\");\n    }\n\n    @Override\n    public MergingDigest createAccumulator() {\n      return new MergingDigest(compression);\n    }\n\n    @Override\n    public MergingDigest addInput(MergingDigest accum, Double value) {\n      accum.add(value);\n      return accum;\n    }\n\n    /** Output the whole structure so it can be queried, reused or stored easily. */\n    @Override\n    public MergingDigest extractOutput(MergingDigest accum) {\n      return accum;\n    }","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sketching/src/main/java/org/apache/beam/sdk/extensions/sketching/TDigestQuantiles.java#L247-L283","documentation":"TDigestQuantilesFn.create(compression) validates that the compression factor is strictly greater than 0 before constructing the function; the compression factor bounds centroid/digest sizes and is meaningless or harmful at zero or below. A non-positive value triggers this IllegalArgumentException immediately at construction time (fail-fast, not at pipeline runtime).","triggerScenarios":"Calling TDigestQuantilesFn.create(0), create(-0.5), or passing a computed/negative variable (e.g. from config parsing) as compression to Sketches.quantiles(...).create(...).","commonSituations":"Config values read as 0 when unset (double default), sign errors when computing compression from other parameters, unit confusion (e.g. passing a percentile 0-1 where a compression >0 is expected and getting 0).","solutions":["Pass a positive compression value; the T-Digest reference default is 100.","Validate config-derived values before calling create(): check compression > 0 and fail with a clear message.","If compression is optional, substitute a sensible default (e.g. 100) when unset instead of 0.","Clamp or reject negative values at configuration load time rather than at transform construction."],"exampleFix":"// before\nTDigestQuantilesFn fn = TDigestQuantilesFn.create(compression); // compression = 0 from config\n\n// after\nif (compression <= 0) {\n  compression = 100.0; // T-Digest default\n}\nTDigestQuantilesFn fn = TDigestQuantilesFn.create(compression);","handlingStrategy":"validation","validationCode":"if (compression == null || Double.isNaN(compression) || compression <= 0) {\n  throw new IllegalArgumentException(\"compression must be > 0, got: \" + compression);\n}","typeGuard":"boolean isValidCompression(double c) { return !Double.isNaN(c) && c > 0.0; }","tryCatchPattern":"try {\n  TDigestQuantilesFn fn = TDigestQuantilesFn.create(compression);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Compression factor\")) {\n    LOG.warn(\"Invalid compression {}, falling back to default 100\", compression);\n    compression = 100.0;\n    fn = TDigestQuantilesFn.create(compression);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Validate pipeline options (options.compression) at startup before building transforms.","Use the T-Digest default of 100 when the parameter is optional.","Avoid passing raw config strings parsed to 0.0 as compression."],"tags":["java","beam","validation","argument","tdigest"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}