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
- Correct the referenced name so it matches an existing field ident exactly
- If a field was renamed, update the index or `at = ...` attribute to the new name
- 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
- Rename fields and their index / `at = ...` references in the same commit
- Keep index definitions directly on the struct they target
- Use the error span — it points at the exact offending identifier
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
- a direct index must be paired with a `#[unique] constraint
- unions not supported
- must specify table accessor, e.g. `#[spacetimedb::table(acce
- spacetimedb table must be a struct
- invalid combination: auto_inc, unique index or primary key c
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/261e27df4cbfef8e.
Report an issue: GitHub.