clockworklabs/SpacetimeDB · error

Invalid sequence: increment must be non-zero

Error message

Invalid sequence: increment must be non-zero

What it means

Third invariant in Sequence::new: increment must be non-zero. A zero step would never advance the sequence, so the constructor panics immediately rather than producing a stuck sequence. Hit when sequence DDL sets INCREMENT BY 0 or a programmatic schema leaves a zero default.

Source

Thrown at crates/datastore/src/locking_tx_datastore/sequence.rs:39

    fn heap_usage(&self) -> usize {
        // MEMUSE: intentionally ignoring schema
        self.value.heap_usage()
    }
}

impl Sequence {
    pub(super) fn new(schema: SequenceSchema, previous_allocation: Option<i128>) -> Self {
        if schema.start < schema.min_value || schema.start > schema.max_value {
            panic!(
                "Invalid sequence: start value {} is out of bounds for sequence with min_value {} and max_value {}",
                schema.start, schema.min_value, schema.max_value
            );
        }
        if schema.max_value <= schema.min_value {
            panic!("Invalid sequence: max_value must be greater than min_value");
        }
        if schema.increment == 0 {
            panic!("Invalid sequence: increment must be non-zero");
        }
        if schema.increment.unsigned_abs() >= (schema.max_value - schema.min_value) as u128 {
            panic!(
                "Invalid sequence: increment must be less than or equal to the range between min_value and max_value"
            );
        }
        let start = if let Some(prev) = previous_allocation {
            if prev < schema.min_value || prev > schema.max_value {
                // Previous versions set allocated to 0 as a default,
                // so we have this special case.
                if prev == 0 {
                    schema.start
                } else {
                    panic!(
                        "Invalid sequence: previous allocation value {prev} is out of bounds for sequence with min_value {} and max_value {}",
                        schema.min_value, schema.max_value
                    );
                }

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Set INCREMENT BY to a non-zero value (1 for typical auto-increment).
  2. Omit the INCREMENT clause to use the default step of 1.
  3. In programmatic schemas, assert increment != 0 before submission.

Example fix

-- before: zero step is rejected
CREATE SEQUENCE s MINVALUE 0 MAXVALUE 100 INCREMENT BY 0;

-- after: valid step
CREATE SEQUENCE s MINVALUE 0 MAXVALUE 100 INCREMENT BY 1;
Defensive patterns

Strategy: validation

Validate before calling

fn increment_valid(s: &SequenceSchema) -> Result<(), String> {
    if s.increment == 0 {
        return Err("increment must be non-zero".into());
    }
    Ok(())
}

Type guard

fn valid_sequence_schema(s: &SequenceSchema) -> bool {
    s.min_value <= s.start && s.start <= s.max_value
        && s.max_value > s.min_value
        && s.increment != 0
        && s.increment.unsigned_abs() < (s.max_value - s.min_value) as u128
}

Prevention

When it happens

Trigger: Creating a sequence with INCREMENT BY 0, or building a SequenceSchema programmatically where increment defaults to 0 before DDL application.

Common situations: Schema code that constructs SequenceSchema with zeroed fields; hand-edited DDL; migration tooling that copies increment from an uninitialized variable.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/25aaf95b635f866c. Report an issue: GitHub.