{"record":{"id":"5c5fd4b1cdcbda68","repo":"apache/druid","slug":"skip-must-be-greater-than-zero","errorCode":null,"errorMessage":"'skip' must be greater than zero","messagePattern":"'skip' must be greater than zero","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/guava/SkippingSequence.java","lineNumber":40,"sourceCode":"import org.apache.druid.java.util.common.IAE;\n\nimport java.io.IOException;\n\n/**\n * A Sequence that skips the first few elements.\n */\npublic class SkippingSequence<T> extends YieldingSequenceBase<T>\n{\n  private final Sequence<T> baseSequence;\n  private final long skip;\n\n  public SkippingSequence(Sequence<T> baseSequence, long skip)\n  {\n    this.baseSequence = baseSequence;\n    this.skip = skip;\n\n    if (skip < 1) {\n      throw new IAE(\"'skip' must be greater than zero\");\n    }\n  }\n\n  @Override\n  public <OutType> Yielder<OutType> toYielder(OutType initValue, YieldingAccumulator<OutType, T> accumulator)\n  {\n    final SkippingYieldingAccumulator<OutType> skippingAccumulator = new SkippingYieldingAccumulator<>(accumulator);\n    return wrapYielder(baseSequence.toYielder(initValue, skippingAccumulator), skippingAccumulator);\n  }\n\n  private <OutType> Yielder<OutType> wrapYielder(\n      final Yielder<OutType> yielder,\n      final SkippingYieldingAccumulator<OutType> accumulator\n  )\n  {\n    return new Yielder<>()\n    {\n      @Override","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/guava/SkippingSequence.java#L22-L58","documentation":"SkippingSequence wraps a base Sequence and skips N leading elements per iteration. The constructor validates that skip >= 1; a skip of 0 or negative is meaningless (skipping nothing or backwards) and throws IAE immediately at construction.","triggerScenarios":"new SkippingSequence(baseSequence, 0) or negative skip — e.g. from a limit/offset calculation that produced a non-positive skip value.","commonSituations":"Paging implementations computing skip = page * pageSize when page=0; user-supplied offset configs that bypass validation upstream.","solutions":["Pass a skip value >= 1; if you don't want to skip, use the baseSequence directly","Clamp or skip the wrapper: only wrap in SkippingSequence when offset > 0","Validate the offset/skip parameter at the API boundary before constructing the sequence"],"exampleFix":"// before\nSequence<T> seq = new SkippingSequence<>(base, offset); // offset=0 -> IAE\n// after\nSequence<T> seq = offset > 0 ? new SkippingSequence<>(base, offset) : base;","handlingStrategy":"validation","validationCode":"if (skip < 1) throw new IllegalArgumentException(\"skip must be >= 1\");\nSequence<T> seq = skip > 0 ? new SkippingSequence<>(base, skip) : base;","typeGuard":"boolean validSkip = skip >= 1;","tryCatchPattern":"try { seq = new SkippingSequence<>(base, skip); } catch (IllegalArgumentException e) { seq = base; }","preventionTips":["Compute skip from page math with Math.max(1, page*pageSize) only when paging is active","Validate offset/skip parameters at the API boundary","Prefer the base sequence directly when skip == 0"],"tags":["sequence","offset","invalid-argument","druid"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}