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

  1. Add accessor = <accessor-name> to the attribute, e.g. #[spacetimedb::view(public, accessor = person)].
  2. If unsure of the name, use the snake_case suggestion the error message already prints from your view function's identifier.
  3. 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

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


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)