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
Every `#[spacetimedb::view]` must explicitly opt in with `public` (currently the only visibility), keeping the access decision explicit. The check runs after the accessor check, so if both are missing you will see the accessor error first. Emitted at call site when `public` was not among the arguments.
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 524b4487d9)
Solutions
- Add `public` to the attribute: `#[spacetimedb::view(accessor = v, public)]`
- If an accessor error also appears, fix it first — it is checked before this one
Example fix
// before
#[spacetimedb::view(accessor = top_scores)]
fn top_scores() -> impl Query<Score> { ... }
// after
#[spacetimedb::view(accessor = top_scores, public)]
fn top_scores() -> impl Query<Score> { ... } Defensive patterns
Strategy: validation
Validate before calling
# list view attributes lacking public grep -rn 'spacetimedb::view' src/ | grep -v public || echo OK
Prevention
- Write `public` in every view attribute — it is mandatory, not a default
- Fix any accessor error first; public is checked second
- Review view declarations in the same pass as table declarations after upgrades
When it happens
Trigger: `#[spacetimedb::view(accessor = v)]` with `accessor` present but `public` absent.
Common situations: Copying a view declaration and dropping the `public` argument; assuming views are public by default.
Related errors
- must specify view accessor, e.g. `#[spacetimedb::view(access
- unions not supported
- must specify table accessor, e.g. `#[spacetimedb::table(acce
- a direct index must be paired with a `#[unique] constraint
- not a column of the table
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/b87f9fac00643889.
Report an issue: GitHub.