cube-js/cube · error · syn::Error
Only trait can be annotated as a service
Error message
Only trait can be annotated as a service
What it means
The #[native_bridge] macro must be applied to a trait definition because it generates service plumbing (dispatch/deserialization) around the trait's methods. When the annotated item is anything else — a struct, enum, impl, module, function — the macro's parser hits the `x =>` catch-all match arm and emits this error.
Source
Thrown at rust/cube/cubesqlplanner/nativebridge/src/lib.rs:156
method_params.is_vec,
)
.unwrap(),
method_params,
})
}
_ => None,
})
.collect::<Vec<_>>();
NativeService {
ident: trait_item.ident.clone(),
methods,
static_data_type: None,
without_imports: false,
with_static_meta: false,
}
}
x => {
return Err(syn::Error::new(
x.span(),
"Only trait can be annotated as a service",
))
}
};
Ok(svc)
}
}
impl NativeService {
fn parse_method_typed_args(args: &Vec<FnArg>) -> syn::Result<Vec<NativeArgumentTyped>> {
args.iter()
.filter_map(|a| match a {
FnArg::Typed(ty) => match ty.pat.as_ref() {
Pat::Ident(id) => {
let dyn_type = Self::get_type_from_possible_dyn_type(&ty.ty);
match dyn_type {
Ok(dyn_type) => Some(Ok(NativeArgumentTyped {View on GitHub (pinned to 7d981676b3)
Solutions
- Move the #[native_bridge] attribute so it is directly above a `trait` declaration.
- If the item is a struct/enum, define a separate trait and annotate that instead.
- Verify no intervening attributes or statements cause the macro to attach to the wrong item.
Example fix
// before
#[native_bridge]
struct MyService;
// after
#[native_bridge]
trait MyService {
fn run(&self) -> Result<String>;
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure the attribute target is a trait
code
.trim_start_matches("#[native_bridge]")
.trim_start()
.starts_with("trait")
.then_some(())
.expect("#[native_bridge] must annotate a trait"); Prevention
- Always place #[native_bridge] directly above a `trait` keyword
- Never leave a blank line/other item between the attribute and the trait
- Review diffs that move attributes across items
When it happens
Trigger: Writing #[native_bridge] on `struct Foo {...}`, `enum Bar {...}`, `impl Foo {...}`, `fn baz() {...}`, or `mod qux {...}` instead of on a `trait` declaration.
Common situations: Copy-pasting the attribute onto the wrong item, applying it above a struct plus a trait (attribute binds to the struct), or misunderstanding that the macro is service-trait-only.
Related errors
- unknown native_bridge flag (expected `without_imports` or `w
- Return type should be {}
- Return type should be Result<_>
- Return type should be {expected_type}
- Return type should be Result<Option<_>>
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/df731ca93403b69d.
Report an issue: GitHub.