{"record":{"id":"22f980a651e53016","repo":"cube-js/cube","slug":"return-type-should-be-result-option","errorCode":null,"errorMessage":"Return type should be Result<Option<_>>","messagePattern":"Return type should be Result<Option<_>>","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"rust/cube/cubesqlplanner/nativebridge/src/lib.rs","lineNumber":293,"sourceCode":"    }\n\n    fn extract_output_for_nested_type(\n        args: &PathArguments,\n        type_to_extract: &str,\n        expected_type: &str,\n    ) -> syn::Result<PathArguments> {\n        let error_message = format!(\"Return type should be {expected_type}\");\n        match args {\n            syn::PathArguments::AngleBracketed(args) => {\n                let arg = args\n                    .args\n                    .first()\n                    .ok_or(syn::Error::new(args.span(), error_message.clone()))?;\n                match arg {\n                    syn::GenericArgument::Type(tp) => match tp {\n                        Type::Path(tp) => {\n                            let segs = &tp.path.segments;\n                            let seg = segs.last().ok_or(syn::Error::new(\n                                tp.span(),\n                                \"Return type should be Result<Option<_>>\",\n                            ))?;\n                            if seg.ident.to_string() == type_to_extract {\n                                let args = &seg.arguments;\n                                Ok(args.clone())\n                            } else {\n                                Err(syn::Error::new(seg.span(), error_message.clone()))\n                            }\n                        }\n                        _ => Err(syn::Error::new(arg.span(), error_message.clone())),\n                    },\n                    _ => Err(syn::Error::new(arg.span(), error_message.clone())),\n                }\n            }\n            _ => Err(syn::Error::new(args.span(), error_message.clone())),\n        }\n    }","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/rust/cube/cubesqlplanner/nativebridge/src/lib.rs#L275-L311","documentation":"When unwrapping the nested wrapper inside Result, extract_output_for_nested_type checks that the inner path's last segment is the expected wrapper (type_to_extract, e.g. Option). If the inner type is not that wrapper — e.g. `Result<Vec<T>>` where `Result<Option<T>>` was expected — it fails with the hardcoded message 'Return type should be Result<Option<_>>'.","triggerScenarios":"A bridged method with an optional output declared as `fn f(&self) -> Result<String>;` or `-> Result<Vec<String>>;` while the macro's optional flag is set (expected shape Result<Option<_>>).","commonSituations":"Mismatch between the helper flags/how the output was detected as optional and the actual written return type; changing Option to Vec (or removing it) after the signature was already validated for Option.","solutions":["Make the inner type exactly match the expected wrapper: use `Result<Option<T>>` when the output is optional.","If a Vec is intended, ensure the method is declared as `Result<Vec<T>>` and that no optional-flag mismatch exists in the surrounding signature.","Avoid aliases or deeply nested wrappers; write the canonical shape directly."],"exampleFix":"// before\nfn find(&self) -> Result<Vec<String>>; // macro expects Result<Option<_>> here\n\n// after\nfn find(&self) -> Result<Option<String>>;","handlingStrategy":"validation","validationCode":"fn matches_expected_shape(sig: &str, wrapper: &str) -> bool {\n    let expected = format!(\"Result<{}<\", wrapper);\n    sig.contains(&expected)\n}\n// assert!(matches_expected_shape(\"fn f() -> Result<Option<String>>;\", \"Option\"));\n// assert!(!matches_expected_shape(\"fn f() -> Result<Vec<String>>;\", \"Option\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match the wrapper (Option vs Vec) to the semantic intent of the method","Do not swap Option/Vec in signatures without updating the expected shape","Keep one canonical shape per method kind across the service"],"tags":["proc-macro","compile-time","rust","generics"],"backgroundTag":"return-type-shape-mismatch","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}