{"record":{"id":"4ae832721ccb461b","repo":"cube-js/cube","slug":"nativebridgestatic-requires-a-struct-with-named-fi","errorCode":null,"errorMessage":"NativeBridgeStatic requires a struct with named fields","messagePattern":"NativeBridgeStatic requires a struct with named fields","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"rust/cube/cubesqlplanner/nativebridge/src/lib.rs","lineNumber":915,"sourceCode":"    TokenStream::from(expanded)\n}\n\nfn collect_static_field_meta_entries(\n    input: &DeriveInput,\n) -> syn::Result<Vec<proc_macro2::TokenStream>> {\n    let data = match &input.data {\n        Data::Struct(d) => d,\n        _ => {\n            return Err(syn::Error::new(\n                input.span(),\n                \"NativeBridgeStatic can only be derived for structs\",\n            ))\n        }\n    };\n    let fields = match &data.fields {\n        Fields::Named(named) => &named.named,\n        _ => {\n            return Err(syn::Error::new(\n                input.span(),\n                \"NativeBridgeStatic requires a struct with named fields\",\n            ))\n        }\n    };\n\n    let mut entries = Vec::new();\n    for field in fields {\n        let ident = field.ident.as_ref().unwrap();\n        let name_str = ident.to_string();\n        let mut js_name: Option<String> = None;\n        let mut skip = false;\n        for attr in &field.attrs {\n            if attr.path().is_ident(\"serde\") {\n                // Best-effort: serde supports many options with `= value` shapes\n                // (e.g. `default = \"fn\"`) that parse_nested_meta cannot pass\n                // through to our callback unchanged, so we swallow errors and\n                // pick up only the `rename = \"...\"` shape we care about.","sourceCodeStart":897,"sourceCodeEnd":933,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube/cubesqlplanner/nativebridge/src/lib.rs#L897-L933","documentation":"`NativeBridgeStatic` requires a struct with named fields because the macro generates metadata keyed by field name. This error fires for structs with unnamed (tuple) fields or unit structs, since there are no names to emit into the static field table.","triggerScenarios":"Applying `#[derive(NativeBridgeStatic)]` to a tuple struct (`struct Foo(u32, String)`) or a unit struct (`struct Foo;`).","commonSituations":"Using tuple structs for convenience (e.g. newtypes) while keeping the derive; converting a named struct into a newtype wrapper; auto-generated tuple structs from other macros.","solutions":["Give the struct named fields: `struct Foo { value: u32 }` instead of `struct Foo(u32)`.","Unwrap newtype wrappers and derive on the inner named-field struct.","Remove the derive if tuple/unit shape is required and generate metadata manually."],"exampleFix":"// before\n#[derive(NativeBridgeStatic)]\nstruct Config(u32);\n// after\n#[derive(NativeBridgeStatic)]\nstruct Config { value: u32 }","handlingStrategy":"validation","validationCode":"// Confirm the struct uses named fields, not tuple/unit form:\nfn has_named_fields(decl: &str) -> bool {\n    let body = decl.split('{').nth(1).unwrap_or(\"\");\n    body.contains(':') // named field like `value: u32`\n}","typeGuard":"fn is_named_field_struct(kind: &str, has_brace_body: bool) -> bool { kind == \"struct\" && has_brace_body }","tryCatchPattern":null,"preventionTips":["Avoid tuple/newtype structs for bridge-static payloads; always use named fields.","When wrapping data in newtypes, derive on the inner named-field struct instead.","Lint for `derive(...NativeBridgeStatic...)` immediately followed by `(` (tuple struct)."],"tags":["rust","proc-macro","derive","compile-time"],"backgroundTag":"unsupported-derive-target","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}