clockworklabs/SpacetimeDB · error · syn::Error
scheduled tables must have a `#[primary_key] #[auto_inc]…
Error message
scheduled tables must have a `#[primary_key] #[auto_inc] scheduled_id: u64` column
What it means
Compile-time error from the #[spacetimedb::table] procedural macro. A table declared with the scheduled = <reducer> argument is the persistence backing of a scheduled reducer, and the runtime requires it to carry an auto-incrementing primary key named scheduled_id of type u64. When the macro walks the struct's columns and finds none annotated with both #[primary_key] and #[auto_inc], it emits this syn::Error at the span of the scheduled(...) attribute and aborts compilation. The same code path separately requires a scheduled_at: spacetimedb::ScheduleAt column (customizable via at = ...).
Solutions
- Add a #[primary_key] #[auto_inc] scheduled_id: u64 field to the scheduled table struct.
- Ensure the column is exactly scheduled_id of type u64 with both field attributes present (not id, not u32, not a single attribute).
- Also verify the scheduled_at: spacetimedb::ScheduleAt column exists - the macro raises a parallel diagnostic for it right before this one; fix both before rebuilding.
Example fix
// before
#[spacetimedb::table(scheduled = tick)]
struct Tick {
at: spacetimedb::ScheduleAt,
}
// after
#[spacetimedb::table(scheduled = tick)]
struct Tick {
#[primary_key]
#[auto_inc]
scheduled_id: u64,
scheduled_at: spacetimedb::ScheduleAt,
} Defensive patterns
Strategy: validation
Prevention
- When adding scheduled = ... to a table, immediately add both required columns: #[primary_key] #[auto_inc] scheduled_id: u64 and scheduled_at: spacetimedb::ScheduleAt.
- Keep a known-good scheduled table in the project as a template and copy it when creating new ones.
- Fix both macro diagnostics (missing scheduled_at and missing scheduled_id) in one pass before rebuilding.
When it happens
Trigger: Declaring #[spacetimedb::table(scheduled = my_reducer)] on a struct that has no scheduled_id column, or one that misses #[primary_key] or #[auto_inc], uses a different name (id) or type (u32), or applies only one of the two required field attributes.
Common situations: Writing a first scheduled table by copying a plain table and only adding the scheduled argument; following an outdated tutorial or AI-generated example that omits the id column; upgrading SpacetimeDB versions where scheduled-table column requirements changed.
Related errors
- must specify view accessor, e.g. `#
- views must be `public`, e.g. `#[view(public)]`
- Cannot convert to : expected bigint, integer number, or…
- Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`
- Timestamp is outside of the representable range for ISO…
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/e9a307664aef1bef.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-macro/src/table.rs:1104
return Err(syn::Error::new(
sched.span,
"scheduled table missing required columns; add these to your struct:\n\
#[primary_key]\n\
#[auto_inc]\n\
scheduled_id: u64,\n\
scheduled_at: spacetimedb::ScheduleAt,",
));
}
let scheduled_at_column = scheduled_at_column.ok_or_else(|| {
syn::Error::new(
sched.span,
"scheduled tables must have a `scheduled_at: spacetimedb::ScheduleAt` column. \
if the column has a name besides `scheduled_at`, you can specify it with \
`scheduled(my_reducer, at = custom_scheduled_at)`",
)
})?;
let primary_key_column = primary_key_column.ok_or_else(|| {
syn::Error::new(
sched.span,
"scheduled tables must have a `#[primary_key] #[auto_inc] scheduled_id: u64` column",
)
})?;
let reducer_or_procedure = &sched.reducer_or_procedure;
let scheduled_at_id = scheduled_at_column.index;
let desc = quote!(spacetimedb::table::ScheduleDesc {
reducer_or_procedure_name: <#reducer_or_procedure as spacetimedb::rt::FnInfo>::NAME,
scheduled_at_column: #scheduled_at_id,
});
let primary_key_ty = primary_key_column.ty;
let scheduled_at_ty = scheduled_at_column.ty;
let typecheck = quote! {
spacetimedb::rt::scheduled_typecheck::<
#original_struct_ident,
<#reducer_or_procedure as spacetimedb::rt::FnInfo>::FnKind,View on GitHub (pinned to 6dee26c6ef)