risingwavelabs/risingwave · error
type inference for this function should be specially handled
Error message
type inference for this function should be specially handled in frontend, and should not call sig.type_infer
What it means
The `#[define_function!]`-style macro lets authors mark a function's type inference as `type_infer = "unreachable"`, generating a closure that panics if invoked. This panic message signals that the function's return type must be inferred by the frontend and `sig.type_infer` must never be called at runtime.
Source
Thrown at src/expr/macro/src/gen.rs:84
if ret == "auto" {
ret = types::min_compatible_type(&args);
}
let attr = FunctionAttr {
args: args.iter().map(|s| s.to_string()).collect(),
ret: ret.to_owned(),
..self.clone()
};
attrs.push(attr);
}
attrs
}
/// Generate the type infer function: `fn(&[DataType]) -> Result<DataType>`
fn generate_type_infer_fn(&self) -> Result<TokenStream2> {
if let Some(func) = &self.type_infer {
if func == "unreachable" {
return Ok(
quote! { |_| unreachable!("type inference for this function should be specially handled in frontend, and should not call sig.type_infer") },
);
}
// use the user defined type inference function
return Ok(func.parse().unwrap());
} else if self.ret == "any" {
// TODO: if there are multiple "any", they should be the same type
if let Some(i) = self.args.iter().position(|t| t == "any") {
// infer as the type of "any" argument
return Ok(quote! { |args| Ok(args[#i].clone()) });
}
if let Some(i) = self.args.iter().position(|t| t == "anyarray") {
// infer as the element type of "anyarray" argument
return Ok(quote! { |args| Ok(args[#i].as_list_elem().clone()) });
}
} else if self.ret == "anyarray" {
if let Some(i) = self.args.iter().position(|t| t == "anyarray") {
// infer as the type of "anyarray" argument
return Ok(quote! { |args| Ok(args[#i].clone()) });View on GitHub (pinned to 6469eb736d)
Solutions
- Implement frontend type inference for this function so the backend infer path is never used
- Change the macro declaration to provide a real `type_infer = "|args| Ok(...)"` closure
- Trace the caller of sig.type_infer and route it to the frontend-specialized path
Example fix
// before TypeInfer::Unreachable // after TypeInfer::from_closure(|args| Ok(DataType::Varchar)) // or implement frontend inference
Defensive patterns
Strategy: validation
Validate before calling
// before registering a function with type_infer = "unreachable", assert the frontend infers its type: assert!(frontend_infer_return_type(func_id, arg_types).is_ok(), "frontend must infer this function's type");
Try / catch
match sig.type_infer(args) {
Err(e) if e.to_string().contains("specially handled in frontend") => frontend_infer_return_type(func_id, args),
other => other,
} Prevention
- Pair every `unreachable` type_infer declaration with a frontend inference rule
- Add a lint/test that all functions in the registry are inferable by the frontend
- Never call sig.type_infer for frontend-special functions
When it happens
Trigger: Calling type inference at runtime on a function descriptor generated with `type_infer = "unreachable"` — i.e. a function whose return type depends on arguments (e.g. casts, array elem access) that the frontend must resolve specially.
Common situations: Adding a new function with `unreachable` inference but forgetting to register frontend type inference; batch/stream executor falling back to generic inference for such a function.
Related errors
- type inference function cannot be automatically derived. You
- data type must be DataType::List
- You can't use the macro on this type
- Expected #[serde_prefix_all(skip)]
- invalid prebuild syntax
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/9212acc145292812.
Report an issue: GitHub.