clockworklabs/SpacetimeDB · error · syn::Error
must specify view accessor, e.g. `#
Error message
must specify view accessor, e.g. `#[spacetimedb::view(accessor = {view})]` What it means
Compile-time error from the #[spacetimedb::view] procedural macro. A view must declare which table accessor it projects over via the accessor = <expr> key-value argument (e.g. accessor = person, referring to the accessor generated by #[spacetimedb::table]). If attribute parsing finishes without an accessor key, the macro derives a snake_case suggestion from the view function's identifier and raises this error at the attribute's call site.
Solutions
- Add accessor = <accessor-name> to the attribute, e.g. #[spacetimedb::view(public, accessor = person)].
- If unsure of the name, use the snake_case suggestion the error message already prints from your view function's identifier.
- Check the key spelling - unknown keys are silently skipped by the parser, so a typo produces this error even though an argument looks present.
Example fix
// before
#[spacetimedb::view(public)]
fn adults() -> impl Query<Person> { /* ... */ }
// after
#[spacetimedb::view(public, accessor = person)]
fn adults() -> impl Query<Person> { /* ... */ } Defensive patterns
Strategy: validation
Prevention
- Always write views with both required arguments: public and accessor = ...
- Copy the attribute list from an existing working view in the project.
- Remember unknown/misspelled attribute keys are ignored by the parser - double-check spelling when this error appears despite an argument being present.
When it happens
Trigger: Applying #[spacetimedb::view] or #[spacetimedb::view(...)] without an accessor = ... key-value pair; misspelling the key (accessors =, table =) so the parser skips it and accessor stays None.
Common situations: Writing a new view and forgetting the accessor; renaming a table's accessor without updating the view attribute; moving to a bindings version where accessor became mandatory.
Related errors
- views must be `public`, e.g. `#[view(public)]`
- scheduled tables must have a `#[primary_key] #[auto_inc]…
- AddView: view ` ` not found in new module def
- Cannot convert to : expected bigint, integer number, or…
- Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/9d3f03a5b443cf95.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-macro/src/view.rs:83
sym::public => {
check_duplicate_msg(&public, &meta, "`public` already specified")?;
public = Some(());
}
sym::accessor => {
check_duplicate_msg(&accessor, &meta, "`accessor` already specified")?;
accessor = Some(meta.value()?.parse()?);
}
sym::primary_key => {
check_duplicate_msg(&primary_key, &meta, "`primary_key` already specified")?;
primary_key = Some(ViewPrimaryKeyArg::parse(meta.value()?)?);
}
});
Ok(())
})
.parse2(input)?;
let accessor = accessor.ok_or_else(|| {
let view = func_ident.to_string().to_snake_case();
syn::Error::new(
Span::call_site(),
format_args!("must specify view accessor, e.g. `#[spacetimedb::view(accessor = {view})]"),
)
})?;
let () = public
.ok_or_else(|| syn::Error::new(Span::call_site(), "views must be `public`, e.g. `#[view(public)]`"))?;
Ok(Self {
name,
primary_key,
public: true,
accessor,
})
}
}
/// If `ty` is `impl Query<T>`, returns `Some(T)`. Otherwise `None`.
fn extract_impl_query_inner(ty: &syn::Type) -> Option<&syn::Type> {
if let syn::Type::ImplTrait(impl_trait) = ty {View on GitHub (pinned to 6dee26c6ef)