{"record":{"id":"b87f9fac00643889","repo":"clockworklabs/SpacetimeDB","slug":"views-must-be-public-e-g-view-public","errorCode":null,"errorMessage":"views must be `public`, e.g. `#[view(public)]`","messagePattern":"views must be `public`, e\\.g\\. `#\\[view\\(public\\)\\]`","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/bindings-macro/src/view.rs","lineNumber":89,"sourceCode":"                    accessor = Some(meta.value()?.parse()?);\n                }\n                sym::primary_key => {\n                    check_duplicate_msg(&primary_key, &meta, \"`primary_key` already specified\")?;\n                    primary_key = Some(ViewPrimaryKeyArg::parse(meta.value()?)?);\n                }\n            });\n            Ok(())\n        })\n        .parse2(input)?;\n        let accessor = accessor.ok_or_else(|| {\n            let view = func_ident.to_string().to_snake_case();\n            syn::Error::new(\n                Span::call_site(),\n                format_args!(\"must specify view accessor, e.g. `#[spacetimedb::view(accessor = {view})]\"),\n            )\n        })?;\n        let () = public\n            .ok_or_else(|| syn::Error::new(Span::call_site(), \"views must be `public`, e.g. `#[view(public)]`\"))?;\n        Ok(Self {\n            name,\n            primary_key,\n            public: true,\n            accessor,\n        })\n    }\n}\n\n/// If `ty` is `impl Query<T>`, returns `Some(T)`. Otherwise `None`.\nfn extract_impl_query_inner(ty: &syn::Type) -> Option<&syn::Type> {\n    if let syn::Type::ImplTrait(impl_trait) = ty {\n        for bound in &impl_trait.bounds {\n            if let syn::TypeParamBound::Trait(trait_bound) = bound\n                && let Some(seg) = trait_bound.path.segments.last()\n                && seg.ident == \"Query\"\n                && let syn::PathArguments::AngleBracketed(args) = &seg.arguments\n                && let Some(syn::GenericArgument::Type(inner)) = args.args.first()","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-macro/src/view.rs#L71-L107","documentation":"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.","triggerScenarios":"`#[spacetimedb::view(accessor = v)]` with `accessor` present but `public` absent.","commonSituations":"Copying a view declaration and dropping the `public` argument; assuming views are public by default.","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"],"exampleFix":"// before\n#[spacetimedb::view(accessor = top_scores)]\nfn top_scores() -> impl Query<Score> { ... }\n\n// after\n#[spacetimedb::view(accessor = top_scores, public)]\nfn top_scores() -> impl Query<Score> { ... }","handlingStrategy":"validation","validationCode":"# list view attributes lacking public\ngrep -rn 'spacetimedb::view' src/ | grep -v public || echo OK","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["rust","proc-macro","spacetimedb","view","compile-time"],"backgroundTag":"missing-required-attribute","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}