clockworklabs/SpacetimeDB · error · syn::Error
views must be `public`, e.g. `#[view(public)]`
Error message
views must be `public`, e.g. `#[view(public)]`
What it means
Compile-time error from the #[spacetimedb::view] macro, raised right after the accessor check: every SpacetimeDB view must currently be public, so when the attribute list lacks the public flag the macro refuses to expand rather than defaulting to private. It is reported at the attribute's call site.
Solutions
- Add the public flag: #[spacetimedb::view(public, accessor = person)].
- If you wanted a non-public view, note the macro currently requires public on all views - keep it as a plain query helper instead.
Example fix
// before #[spacetimedb::view(accessor = person)] // after #[spacetimedb::view(public, accessor = person)]
Defensive patterns
Strategy: validation
Prevention
- Every #[spacetimedb::view] needs the public flag - write public and accessor = ... together as a pair.
- Run cargo check right after adding a view so both view macro diagnostics surface in one pass.
When it happens
Trigger: Declaring a view whose attribute list has accessor = ... but not the word public, e.g. #[spacetimedb::view(accessor = person)].
Common situations: Authors expecting a private default for views; converting a query helper into a view and carrying over only the accessor argument; writing pub or pub(crate) instead of public inside the attribute (unknown words are ignored).
Related errors
- must specify view accessor, e.g. `#
- 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/b87f9fac00643889.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-macro/src/view.rs:89
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 {
for bound in &impl_trait.bounds {
if let syn::TypeParamBound::Trait(trait_bound) = bound
&& let Some(seg) = trait_bound.path.segments.last()
&& seg.ident == "Query"
&& let syn::PathArguments::AngleBracketed(args) = &seg.arguments
&& let Some(syn::GenericArgument::Type(inner)) = args.args.first()View on GitHub (pinned to 6dee26c6ef)