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

  1. Move the #[native_bridge] attribute so it is directly above a `trait` declaration.
  2. If the item is a struct/enum, define a separate trait and annotate that instead.
  3. 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

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


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/df731ca93403b69d. Report an issue: GitHub.