{"record":{"id":"3858d3331189d988","repo":"clockworklabs/SpacetimeDB","slug":"precheck-failed-added-sequence-sequence-name-ha","errorCode":null,"errorMessage":"Precheck failed: added sequence {sequence_name} has invalid min value","messagePattern":"Precheck failed: added sequence (.+?) has invalid min value","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/engine/src/update.rs","lineNumber":240,"sourceCode":"                let sequence_def: &SequenceDef = plan.new.lookup(key).ok_or_else(|| {\n                    anyhow::anyhow!(\"Precheck: sequence `{sequence_name}` not found in new module def\")\n                })?;\n                let table_full_name = joined(namespace, &table_def.name);\n                let table_id = stdb.table_id_from_name_mut(tx, &table_full_name)?.unwrap();\n\n                let ty = table_def\n                    .get_column(sequence_def.column)\n                    .ok_or_else(|| {\n                        anyhow::anyhow!(\"Precheck failed: added sequence {sequence_name} refers to unknown column\")\n                    })?\n                    .ty\n                    .clone();\n\n                // Convert `SequenceDef` min/max to `AlgebraicValue`s of the correct type.\n                let min = ty\n                    .saturating_value_from_i128(sequence_def.min_value.unwrap_or(1))\n                    .ok_or_else(|| {\n                        anyhow::anyhow!(\"Precheck failed: added sequence {sequence_name} has invalid min value\")\n                    })?;\n\n                let max = match sequence_def.max_value {\n                    Some(max) => ty.saturating_value_from_i128(max),\n                    None => ty.saturating_value_from_i128(i128::MAX),\n                }\n                .ok_or_else(|| {\n                    anyhow::anyhow!(\"Precheck failed: added sequence {sequence_name} has invalid max value\")\n                })?;\n\n                let range = min..=max;\n                if stdb\n                    .iter_by_col_range_mut(tx, table_id, sequence_def.column, range)?\n                    .next()\n                    .is_some()\n                {\n                    anyhow::bail!(\"Precheck failed: added sequence {sequence_name} already has values in range\",);\n                }","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/engine/src/update.rs#L222-L258","documentation":"Auto-migrate precheck: converting the sequence's min value (sequence_def.min_value, defaulting to 1) into the sequenced column's type via saturating_value_from_i128 returned None, i.e. the min is not representable as that column's algebraic type — typically because the column is not an integer type at all.","triggerScenarios":"Adding a sequence whose column's type cannot represent the min value (non-integer column, or an integer type that cannot hold the declared min); a module def declaring min_value below/above what the column type can represent where even saturation is not applicable.","commonSituations":"Putting a sequence attribute on a non-integer column in the module; widening/narrowing the sequenced column in the same publish that adds the sequence; hand-authored defs with unchecked min values.","solutions":["Make the sequenced column an integer type wide enough for the declared min (e.g. u64/i64 identity columns)","Set an explicit min_value that fits the column type, or remove the custom min","Validate the module def (sequence column type vs min) before publishing"],"exampleFix":"// before: non-integer sequenced column\n#[sequence(column = \"name\")]\nstruct T { name: String }\n\n// after: integer identity column\n#[sequence(column = \"id\")]\nstruct T { id: u64, name: String }","handlingStrategy":"validation","validationCode":"// Check the sequenced column is an integer type that can hold the min\nuse spacetimedb_lib::AlgebraicType;\nfn sequence_min_ok(col_ty: &AlgebraicType, min: i128) -> bool {\n    col_ty.saturating_value_from_i128(min).is_some()\n}","typeGuard":"fn is_integer_col(ty: &AlgebraicType) -> bool {\n    matches!(t, AlgebraicType::U8 | AlgebraicType::U16 | AlgebraicType::U32\n        | AlgebraicType::U64 | AlgebraicType::U128 | AlgebraicType::I8\n        | AlgebraicType::I16 | AlgebraicType::I32 | AlgebraicType::I64 | AlgebraicType::I128)\n}","tryCatchPattern":"match auto_migrate_database(&stdb, &mut tx, auth, &plan, &logger) {\n    Err(e) if e.to_string().contains(\"invalid min value\") => {\n        anyhow::bail!(\"module error: {e:#}; use an integer sequence column or an explicit fitting min\");\n    }\n    r => r,\n}","preventionTips":["Only put sequences on integer identity columns (u64/i64)","Set explicit min/max only when they fit the column type","Validate sequence bounds in module lints before publish"],"tags":["rust","spacetimedb","migration","sequence","type-mismatch"],"backgroundTag":"migration-plan-invalid","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}