cube-js/cube · error · syn::Error
Type::Path is expected
Error message
Type::Path is expected
What it means
`get_type_from_possible_dyn_type` only understands plain type paths (`std::path::Type::Path`). If the inner return type of a native-bridge function is any other syntax form — a reference `&T`, a slice `[T]`, a tuple, a trait object directly, a pointer, or `impl Trait` — the macro cannot generate deserialization code and throws 'Type::Path is expected'.
Source
Thrown at rust/cube/cubesqlplanner/nativebridge/src/lib.rs:371
original_type,
dynamic_container_path: Some(dynamic_container_path),
})
} else {
Ok(NativeOutputParams {
type_path: tp.path.clone(),
original_type: tp.path.clone(),
dynamic_container_path: None,
})
}
} else {
Ok(NativeOutputParams {
type_path: tp.path.clone(),
original_type: tp.path.clone(),
dynamic_container_path: None,
})
}
}
_ => Err(syn::Error::new(tp.span(), "Type::Path is expected")),
}
}
fn get_dyn_type_for_deserialize(args: &PathArguments) -> Option<Path> {
match args {
syn::PathArguments::AngleBracketed(args) => {
if args.args.is_empty() {
return None;
}
let arg = args.args.first().unwrap();
match arg {
syn::GenericArgument::Type(tp) => match tp {
Type::TraitObject(to) => {
let type_param_bound = to.bounds.first().unwrap();
match type_param_bound {
syn::TypeParamBound::Trait(trait_bound) => {
let mut path = trait_bound.path.clone();View on GitHub (pinned to 7d981676b3)
Solutions
- Change the inner type to a named path type: `String` instead of `&str`, `Vec<u8>` instead of `[u8]`, a struct instead of a tuple.
- For dynamic dispatch, use a smart-pointer path form the macro understands, e.g. `Box<dyn MyTrait>` or `Arc<dyn MyTrait>` (it detects Rc/Arc/Box + trait objects).
- Return owned data only — the bridge serializes values across FFI, so borrowed/pointer types are unsupported.
Example fix
// before
fn native_fn() -> Result<&str> { ... }
// after
fn native_fn() -> Result<Option<String>> { ... } Defensive patterns
Strategy: validation
Validate before calling
// Ensure inner return type is a named path type (no refs/slices/tuples/ptrs):
fn inner_is_path_type(sig: &str) -> Result<(), String> {
let bad = ["&", "[", "(", "*", "impl ", "dyn "];
if let Some(inner) = sig.strip_prefix("Result<Option<") {
if bad.iter().any(|b| inner.trim_start().starts_with(b)) {
return Err(format!("inner type must be a path type: {sig}"));
}
}
Ok(())
} Type guard
fn is_named_path_type(t: &str) -> bool { let t = t.trim(); t.chars().next().map_or(false, |c| c.is_alphabetic() || c == '_') && !t.starts_with("impl ") && !t.starts_with("dyn ") && !t.starts_with('&') } Prevention
- Use `String`/`Vec<u8>`/structs instead of `&str`, slices, tuples, or raw pointers in returns.
- For dynamic dispatch use `Box<dyn Trait>` / `Arc<dyn Trait>` path forms, which the macro recognizes.
- Remember FFI bridges serialize owned values — design return types accordingly.
When it happens
Trigger: Declaring a native-bridge return like `Result<&str>`, `Result<[u8; N]>`, `Result<(A, B)>`, `Result<*const T>`, or `Result<impl Trait>`; anything whose inner type is not a named path type.
Common situations: Copying idiomatic Rust signatures (references, tuples, slices) into macro-annotated native functions; trying to return borrowed data across the FFI boundary; returning trait objects directly instead of `Box<dyn Trait>` path forms.
Related errors
- Return type should be {}
- Return type should be Result<_>
- unknown native_bridge flag (expected `without_imports` or `w
- Only trait can be annotated as a service
- Return type should be {expected_type}
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/0ef93b1b2b94bca7.
Report an issue: GitHub.