clockworklabs/SpacetimeDB · critical
Someone put a forbidden variant in the system table!
Error message
Someone put a forbidden variant in the system table!
What it means
Constraint rows read from the st_constraints system table are converted into ConstraintSchema via From<StConstraintRow> when loading schema. The StConstraintData::Unused variant is the catch-all for forbidden/unknown constraint tags, and converting it panics. Seeing this panic means a system-table row decoded to an unrecognized constraint kind: version skew between the build that wrote the data and the build reading it, or corrupted system-table data.
Source
Thrown at crates/datastore/src/system_tables.rs:1407
read_via_bsatn(row)
}
}
impl From<StConstraintRow> for ProductValue {
fn from(x: StConstraintRow) -> Self {
to_product_value(&x)
}
}
impl From<StConstraintRow> for ConstraintSchema {
fn from(x: StConstraintRow) -> Self {
Self {
constraint_id: x.constraint_id,
constraint_name: x.constraint_name,
table_id: x.table_id,
data: match x.constraint_data {
StConstraintData::Unique { columns } => ConstraintData::Unique(UniqueConstraintData { columns }),
StConstraintData::Unused(_) => panic!("Someone put a forbidden variant in the system table!"),
},
}
}
}
/// System Table [ST_ROW_LEVEL_SECURITY_NAME]
///
/// | table_id | sql |
/// |----------|--------------|
/// | 1 | "SELECT ..." |
#[derive(Debug, Clone, PartialEq, Eq, SpacetimeType)]
#[sats(crate = spacetimedb_lib)]
pub struct StRowLevelSecurityRow {
pub table_id: TableId,
pub sql: RawSql,
}
impl TryFrom<RowRef<'_>> for StRowLevelSecurityRow {View on GitHub (pinned to 6dee26c6ef)
Solutions
- Open the database with the spacetimedb version that wrote it (or one that maps the tag), then export and reimport the data.
- Check release notes for constraint-variant changes and pick a compatible version.
- If it reproduces on a freshly created database, report upstream with the offending constraint row.
Defensive patterns
Strategy: try-catch
Try / catch
// wrap schema loading so an unrecognized constraint variant is reported, not fatal
let loaded = std::panic::catch_unwind(|| db.load_schema());
match loaded {
Ok(schema) => schema,
Err(p) if panic_message(&p).contains("forbidden variant") => {
// system table contains a constraint tag unknown to this build:
// reopen with the version that wrote the data, then export/reimport
}
Err(p) => std::panic::resume_unwind(p),
} Prevention
- Open databases only with spacetimedb builds compatible with the version that wrote them.
- Keep commitlogs backed up before upgrading across major versions.
- Report unrecognized constraint variants upstream with the row contents.
When it happens
Trigger: Booting or loading schema for a database whose st_constraints rows contain a constraint tag that the running build maps to StConstraintData::Unused, hitting the From impl during schema load.
Common situations: Opening a commitlog/database written by a different spacetimedb version with renamed constraint variants; forks that added constraint variants; bit-rot in stored system tables.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- missing system table sequence id for sequence {} of table {}
- system tables cannot have schedules, but table {}: {sch:?}
- unexpected error from `datastore_delete_by_index_scan_range_
- Deletion for non-existent table {table_id:?}... huh?
- When replaying `st_column` update: `table_primary_key` shoul
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/095f7eb9c9e647fd.
Report an issue: GitHub.