{"record":{"id":"df731ca93403b69d","repo":"cube-js/cube","slug":"only-trait-can-be-annotated-as-a-service","errorCode":null,"errorMessage":"Only trait can be annotated as a service","messagePattern":"Only trait can be annotated as a service","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"rust/cube/cubesqlplanner/nativebridge/src/lib.rs","lineNumber":156,"sourceCode":"                                    method_params.is_vec,\n                                )\n                                .unwrap(),\n                                method_params,\n                            })\n                        }\n                        _ => None,\n                    })\n                    .collect::<Vec<_>>();\n                NativeService {\n                    ident: trait_item.ident.clone(),\n                    methods,\n                    static_data_type: None,\n                    without_imports: false,\n                    with_static_meta: false,\n                }\n            }\n            x => {\n                return Err(syn::Error::new(\n                    x.span(),\n                    \"Only trait can be annotated as a service\",\n                ))\n            }\n        };\n        Ok(svc)\n    }\n}\n\nimpl NativeService {\n    fn parse_method_typed_args(args: &Vec<FnArg>) -> syn::Result<Vec<NativeArgumentTyped>> {\n        args.iter()\n            .filter_map(|a| match a {\n                FnArg::Typed(ty) => match ty.pat.as_ref() {\n                    Pat::Ident(id) => {\n                        let dyn_type = Self::get_type_from_possible_dyn_type(&ty.ty);\n                        match dyn_type {\n                            Ok(dyn_type) => Some(Ok(NativeArgumentTyped {","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube/cubesqlplanner/nativebridge/src/lib.rs#L138-L174","documentation":"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.","triggerScenarios":"Writing #[native_bridge] on `struct Foo {...}`, `enum Bar {...}`, `impl Foo {...}`, `fn baz() {...}`, or `mod qux {...}` instead of on a `trait` declaration.","commonSituations":"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.","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."],"exampleFix":"// before\n#[native_bridge]\nstruct MyService;\n\n// after\n#[native_bridge]\ntrait MyService {\n    fn run(&self) -> Result<String>;\n}","handlingStrategy":"validation","validationCode":"// Ensure the attribute target is a trait\ncode\n    .trim_start_matches(\"#[native_bridge]\")\n    .trim_start()\n    .starts_with(\"trait\")\n    .then_some(())\n    .expect(\"#[native_bridge] must annotate a trait\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["proc-macro","compile-time","rust","attribute-macro"],"backgroundTag":"macro-applied-to-wrong-item","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}