clockworklabs/SpacetimeDB · error · syn::Error

not a column of the table

Error message

not a column of the table

What it means

While lowering a table, the macro resolves every column name referenced by index definitions and by the scheduled `at = ...` option against the struct's fields. `find_column` returns this error, with its span on the offending identifier, when no field ident matches. Field renames and copy-pasted index definitions between tables are the usual causes.

Source

Thrown at crates/bindings-macro/src/table.rs:763

    let syn::Type::Path(type_path) = ty else {
        return false;
    };
    type_path
        .path
        .segments
        .last()
        .is_some_and(|segment| segment.ident == "String")
}

fn try_find_column<'a, 'b, T: ?Sized>(cols: &'a [Column<'b>], name: &T) -> Option<&'a Column<'b>>
where
    Ident: PartialEq<T>,
{
    cols.iter().find(|col| col.ident == name)
}

fn find_column<'a, 'b>(cols: &'a [Column<'b>], name: &Ident) -> syn::Result<&'a Column<'b>> {
    try_find_column(cols, name).ok_or_else(|| syn::Error::new(name.span(), "not a column of the table"))
}

enum ColumnAttr {
    Unique(Span),
    AutoInc(Span),
    PrimaryKey(Span),
    Index(IndexArg),
    Default(syn::Expr, Span),
}

impl ColumnAttr {
    fn parse(attr: &syn::Attribute, field_ident: &Ident) -> syn::Result<Option<Self>> {
        let Some(ident) = attr.path().get_ident() else {
            return Ok(None);
        };
        Ok(if ident == sym::index {
            let index = IndexArg::parse_index_attr(field_ident, attr)?;
            Some(ColumnAttr::Index(index))

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Correct the referenced name so it matches an existing field ident exactly
  2. If a field was renamed, update the index or `at = ...` attribute to the new name
  3. If the reference was intentional, add the missing column to the struct

Example fix

// before
#[spacetimedb::table(accessor = inventory, index = btree(item_id))]
struct Inventory {
    id: u64,
    item: String,
}

// after
#[spacetimedb::table(accessor = inventory, index = btree(item))]
struct Inventory {
    id: u64,
    item: String,
}
Defensive patterns

Strategy: validation

Validate before calling

# list index declarations so you can cross-check each referenced ident against struct fields
grep -rEn 'index *= *(btree|hash|direct)' src/

Prevention

When it happens

Trigger: `index = btree(a, b)` / `hash(...)` / `direct(...)` referencing an ident that is not a field of the struct; `scheduled(reducer, at = custom)` where `custom` names no field.

Common situations: Renaming struct fields during a refactor without updating index attributes; copying a table declaration and forgetting to update the index column list.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/261e27df4cbfef8e. Report an issue: GitHub.