cube-js/cube · error · syn::Error
Return type should be Result<Option<_>>
Error message
Return type should be Result<Option<_>>
What it means
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<_>>'.
Source
Thrown at rust/cube/cubesqlplanner/nativebridge/src/lib.rs:293
}
fn extract_output_for_nested_type(
args: &PathArguments,
type_to_extract: &str,
expected_type: &str,
) -> syn::Result<PathArguments> {
let error_message = format!("Return type should be {expected_type}");
match args {
syn::PathArguments::AngleBracketed(args) => {
let arg = args
.args
.first()
.ok_or(syn::Error::new(args.span(), error_message.clone()))?;
match arg {
syn::GenericArgument::Type(tp) => match tp {
Type::Path(tp) => {
let segs = &tp.path.segments;
let seg = segs.last().ok_or(syn::Error::new(
tp.span(),
"Return type should be Result<Option<_>>",
))?;
if seg.ident.to_string() == type_to_extract {
let args = &seg.arguments;
Ok(args.clone())
} else {
Err(syn::Error::new(seg.span(), error_message.clone()))
}
}
_ => Err(syn::Error::new(arg.span(), error_message.clone())),
},
_ => Err(syn::Error::new(arg.span(), error_message.clone())),
}
}
_ => Err(syn::Error::new(args.span(), error_message.clone())),
}
}View on GitHub (pinned to 7d981676b3)
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.
Example fix
// before fn find(&self) -> Result<Vec<String>>; // macro expects Result<Option<_>> here // after fn find(&self) -> Result<Option<String>>;
Defensive patterns
Strategy: validation
Validate before calling
fn matches_expected_shape(sig: &str, wrapper: &str) -> bool {
let expected = format!("Result<{}<", wrapper);
sig.contains(&expected)
}
// assert!(matches_expected_shape("fn f() -> Result<Option<String>>;", "Option"));
// assert!(!matches_expected_shape("fn f() -> Result<Vec<String>>;", "Option")); Prevention
- 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
When it happens
Trigger: 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<_>>).
Common situations: 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.
Related errors
- Return type should be {expected_type}
- unknown native_bridge flag (expected `without_imports` or `w
- Only trait can be annotated as a service
- Return type should be {}
- Return type should be Result<_>
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/22f980a651e53016.
Report an issue: GitHub.