clockworklabs/SpacetimeDB · error · syn::Error
scheduled tables must have a `scheduled_at: spacetimedb::Sch
Error message
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)`
What it means
Scheduled-table validation found a primary-key column but no time column: there is no field named `scheduled_at` and no `at = custom` option resolving to one. The error, emitted at the `scheduled` argument's span, suggests either adding the standard column or pointing `at = ...` at a custom-named `ScheduleAt` column.
Source
Thrown at crates/bindings-macro/src/table.rs:1096
.as_ref()
.map(|sched| {
let scheduled_at_column = match &sched.at {
Some(at) => Some(find_column(&columns, at)?),
None => try_find_column(&columns, "scheduled_at"),
};
// better error message when both are missing
if scheduled_at_column.is_none() && primary_key_column.is_none() {
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,View on GitHub (pinned to 524b4487d9)
Solutions
- Add a `scheduled_at: spacetimedb::ScheduleAt` column
- Or, for a custom column name, declare it with `scheduled(reducer, at = your_column)`
- If the column was removed by mistake, restore it
Example fix
// before
#[spacetimedb::table(accessor = jobs, scheduled(run_jobs))]
struct Jobs {
#[primary_key]
#[auto_inc]
scheduled_id: u64,
fire_at: spacetimedb::ScheduleAt,
}
// after
#[spacetimedb::table(accessor = jobs, scheduled(run_jobs, at = fire_at))]
struct Jobs {
#[primary_key]
#[auto_inc]
scheduled_id: u64,
fire_at: spacetimedb::ScheduleAt,
} Defensive patterns
Strategy: validation
Validate before calling
# scheduled tables missing the time column
grep -rl 'scheduled(' src/ | xargs -r grep -L 'scheduled_at' || echo OK Prevention
- Keep the conventional column name `scheduled_at` unless you pass `at = ...`
- Rename the time column and its `at = ...` reference together
- Run cargo check after any scheduled-table schema change
When it happens
Trigger: A scheduled table where a primary-key column exists but no `scheduled_at` field exists and no `at = ...` reference resolves to a field.
Common situations: Renaming `scheduled_at` (for example to `fire_at`) without adding `at = fire_at`; removing the time column while refactoring the scheduler schema.
Related errors
- scheduled table missing required columns; add these to your
- scheduled tables must have a `#[primary_key] #[auto_inc] sch
- unions not supported
- must specify table accessor, e.g. `#[spacetimedb::table(acce
- a direct index must be paired with a `#[unique] constraint
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/810e84a3fe3e5db9.
Report an issue: GitHub.