apache/beam · error · IllegalArgumentException

For sequence generator, 'start

Error message

For sequence generator, 'start' (%d) cannot be greater than 'end' (%d).

What it means

For a sequence generator the cycle length is computed as end - start + 1, which is invalid when start exceeds end. The builder validates this after parsing both JSON values as longs and throws an IllegalArgumentException naming the offending values.

Solutions

  1. Swap the values so start <= end.
  2. Compute and order min/max programmatically before emitting the properties JSON.
  3. Validate range bounds in your table DDL generation code.

Example fix

// before
'{"fields":{"id":{"kind":"sequence","start":100,"end":1}}}'
// after
'{"fields":{"id":{"kind":"sequence","start":1,"end":100}}}'
Defensive patterns

Strategy: validation

Validate before calling

long s = props.path("fields." + name + ".start").asLong(0);
long e = props.path("fields." + name + ".end").asLong(Long.MAX_VALUE);
if (s > e) throw new IllegalArgumentException(name + ": start > end");

Try / catch

try { buildRowFn(props); } catch (IllegalArgumentException e) { /* swap/normalize bounds */ }

Prevention

When it happens

Trigger: Setting fields.<name>.start greater than fields.<name>.end (e.g. start=100, end=1) with kind='sequence'.

Common situations: Swapping the values by accident; programmatically computing bounds where the order wasn't normalized; editing properties over time until start drifted past end.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/be2bbb047b095d35. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/datagen/DataGeneratorRowFn.java:140

      }

      JsonNode startNode = properties.path("fields." + fieldName + ".start");
      JsonNode endNode = properties.path("fields." + fieldName + ".end");

      if (startNode.isMissingNode() && endNode.isMissingNode()) {
        return (index) -> index;
      }

      if (startNode.isMissingNode() || endNode.isMissingNode()) {
        throw new IllegalArgumentException(
            "For a cycling sequence generator, both 'start' and 'end' must be specified.");
      }

      long start = startNode.asLong(0L);
      long end = endNode.asLong(Long.MAX_VALUE);

      if (start > end) {
        throw new IllegalArgumentException(
            String.format(
                "For sequence generator, 'start' (%d) cannot be greater than 'end' (%d).",
                start, end));
      }
      long cycleLength = end - start + 1;
      switch (sqlTypeName) {
        case INTEGER:
          return (index) -> (int) (start + (index % cycleLength));
        case SMALLINT:
          return (index) -> (short) (start + (index % cycleLength));
        case TINYINT:
          return (index) -> (byte) (start + (index % cycleLength));
        default: // BIGINT
          return (index) -> start + (index % cycleLength);
      }
    }

    switch (sqlTypeName) {

View on GitHub (pinned to 12126d8942)