clockworklabs/SpacetimeDB · error

unique: unexpected error from datastore_delete_by_index_scan

Error message

unique: unexpected error from datastore_delete_by_index_scan_point_bsatn: {e}

What it means

UniqueColumn::delete deletes the row whose unique-column value matches, returning false when no such row exists (normal miss, not an error). The panic fires only when the underlying datastore_delete_by_index_scan_point_bsatn syscall itself returns an error - e.g. the BSATN-encoded key point fails to decode against the index's key type or the index id is invalid for the deployed schema.

Source

Thrown at crates/bindings/src/table.rs:372

    {
        find::<Tbl, Col>(col_val.borrow())
    }

    /// Deletes the row where the value in the unique column matches the supplied `col_val`,
    /// if any such row is present in the database state.
    ///
    /// Returns `true` if a row with the specified `col_val` was previously present and has been deleted,
    /// or `false` if no such row was present.
    #[inline]
    pub fn delete(&self, col_val: impl Borrow<Col::ColType>) -> bool {
        self._delete(col_val.borrow()).0
    }

    fn _delete(&self, col_val: &Col::ColType) -> (bool, IterBuf) {
        let index_id = Col::index_id();
        let point = IterBuf::serialize(col_val).unwrap();
        let n_del = sys::datastore_delete_by_index_scan_point_bsatn(index_id, &point).unwrap_or_else(|e| {
            panic!("unique: unexpected error from datastore_delete_by_index_scan_point_bsatn: {e}")
        });

        (n_del > 0, point)
    }

    /// Deletes the row where the value in the unique column matches that in the corresponding field of `new_row`, and
    /// then inserts the `new_row`.
    ///
    /// Returns the new row as actually inserted, with computed values substituted for any auto-inc placeholders.
    ///
    /// This method can only be called on primary key columns, not any unique column.
    /// This prevents confusion regarding what constitutes a row update vs. a delete+insert.
    /// To perform this operation for a non-primary unique column, call
    /// `.delete(key)` followed by `.insert(row)`.
    ///
    /// # Panics
    /// Panics if no row was previously present with the matching value in the unique column,
    /// or if either the delete or the insertion would violate a constraint.

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Verify the column is actually #[unique] (this API is for unique columns) and that bindings are freshly generated.
  2. Clean rebuild and republish (cargo clean && spacetime publish) so index ids match the deployed schema.
  3. Align the spacetimedb crate version with the host server version; if it still reproduces, file an issue with the errno.
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Module/host schema skew: bindings compiled against an index definition that differs from the deployed one; a column type change (e.g. u32 to u64) so the serialized point no longer matches the index key's AlgebraicType; stale index ids after republishing without a matching rebuild.

Common situations: Redeploying a module with column type changes while the crate and host versions drift; using hand-modified generated table code with wrong index ids.

Related errors


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