clockworklabs/SpacetimeDB · error

Invalid sequence: start value {} is out of bounds for sequen

Error message

Invalid sequence: start value {} is out of bounds for sequence with min_value {} and max_value {}

What it means

Sequence::new validates a SequenceSchema before creating a sequence; the first invariant requires min_value <= start <= max_value. A start outside the declared bounds panics with all three values printed. Reached when DDL (or programmatic schema) defines a sequence, including auto-increment columns, with a start outside its range. Note Sequence::new also takes a previous_allocation (used when reloading schema) and tolerates the legacy default of 0 from older versions, so this specific panic is about the schema's declared start, not prior allocations.

Source

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

    value: i128,
    // The number we have persisted as a lower bound for the next restart.
    // This is the first value to be returned after a restart, so when we
    // reach this value, the user needs to call allocate_steps and update
    // the corresponding system table row.
    allocated: i128,
}

impl MemoryUsage for Sequence {
    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,

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Set START WITH inside [MINVALUE, MAXVALUE], or omit START to default to MINVALUE.
  2. Widen MINVALUE/MAXVALUE to cover the intended start value.
  3. When migrating existing sequences, recompute bounds from the current allocated value before applying.

Example fix

-- before: start outside bounds (100 > MAXVALUE 50)
CREATE SEQUENCE order_seq START WITH 100 MINVALUE 0 MAXVALUE 50;

-- after: start within bounds
CREATE SEQUENCE order_seq START WITH 10 MINVALUE 0 MAXVALUE 1000 INCREMENT BY 1;
Defensive patterns

Strategy: validation

Validate before calling

fn validate_sequence(s: &SequenceSchema) -> Result<(), String> {
    if s.start < s.min_value || s.start > s.max_value {
        return Err(format!("start {} outside [{}, {}]", s.start, s.min_value, s.max_value));
    }
    if s.max_value <= s.min_value { return Err("max_value must be > min_value".into()); }
    if s.increment == 0 { return Err("increment must be non-zero".into()); }
    if s.increment.unsigned_abs() >= (s.max_value - s.min_value) as u128 {
        return Err("|increment| must be < (max_value - min_value)".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 or altering a sequence where START WITH is below MINVALUE or above MAXVALUE, e.g. START WITH 100 MINVALUE 0 MAXVALUE 50; also migrations that shrink bounds below an existing declared start.

Common situations: Hand-written sequence DDL with inconsistent bounds; copy-pasted sequence options between columns; migrations lowering MAXVALUE after data exists.

Related errors


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