risingwavelabs/risingwave · error
multiple UDF implementations found for language: {language}
Error message
multiple UDF implementations found for language: {language} What it means
find_udf_impl resolves the concrete UDF implementation for a given language by filtering registered implementation descriptors with the match_fn. If more than one descriptor matches the same language/runtime/link combination, resolution is ambiguous and it bails — implementations must be uniquely selected.
Source
Thrown at src/expr/core/src/sig/udf.rs:52
/// static MY_UDF_LANGUAGE: UdfImplDescriptor = UdfImplDescriptor {...};
/// ```
#[linkme::distributed_slice]
pub static UDF_IMPLS: [UdfImplDescriptor];
/// Find a UDF implementation by language.
pub fn find_udf_impl(
language: &str,
runtime: Option<&str>,
link: Option<&str>,
) -> Result<&'static UdfImplDescriptor> {
let mut impls = UDF_IMPLS
.iter()
.filter(|desc| (desc.match_fn)(language, runtime, link));
let impl_ = impls.next().context(
"language not found.\nHINT: UDF feature flag may not be enabled during compilation",
)?;
if impls.next().is_some() {
bail!("multiple UDF implementations found for language: {language}");
}
Ok(impl_)
}
/// UDF implementation descriptor.
///
/// Every UDF implementation should provide 3 functions:
pub struct UdfImplDescriptor {
/// Returns if a function matches the implementation.
///
/// This function is used to determine which implementation to use for a UDF.
pub match_fn: fn(language: &str, runtime: Option<&str>, link: Option<&str>) -> bool,
/// Creates a function from options.
///
/// This function will be called when `create function` statement is executed on the frontend.
pub create_fn: fn(opts: CreateOptions<'_>) -> Result<CreateFunctionOutput>,
View on GitHub (pinned to 6469eb736d)
Solutions
- Check enabled cargo features — disable the overlapping/duplicate UDF feature flags
- Fix the duplicate implementation's match_fn so only one matches a given (language, runtime, link)
- Remove the redundant UdfImplDescriptor registration
- Rebuild and confirm only one implementation matches each language
Example fix
// before: two impls both match "python" (desc: |lang, _, _| lang == "python") x2 // after: disambiguate (desc: |lang, runtime, _| lang == "python" && runtime == EmbeddedRuntime::Pyo3)
Defensive patterns
Strategy: try-catch
Validate before calling
// Count matching impls before resolution
let n = UDF_IMPLEMENTS.iter().filter(|d| (d.match_fn)(lang, rt, link)).count();
assert!(n <= 1, "ambiguous UDF impl for {lang}"); Try / catch
match find_udf_impl(lang, rt, link) { Err(e) if e.to_string().contains("multiple UDF implementations") => disable_conflicting_feature(&e), Ok(i) => i, Err(e) => return Err(e) } Prevention
- Enable only one UDF runtime feature per language in Cargo features
- Make each descriptor's match_fn mutually exclusive
- Add a startup assertion that no two descriptors overlap
When it happens
Trigger: Calling find_udf_impl when two or more registered UdfImplDecriptors match the same language (e.g. two 'python' implementations registered due to duplicate feature-flag-gated registrations or a bug in a match_fn that is too permissive).
Common situations: Compiling with conflicting UDF feature flags that each register a 'python' (or other language) runtime; adding a new UDF implementation without narrowing its match_fn; duplicate registration of the same implementation.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- UDF returned a value of type {} while the declared return ty
- UDF aggregate {what} has {} rows, but expected exactly 1
- {0}
- UDF returned {} rows, but expected {}
- UDF returned no columns
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/54f5a1e114adaac5.
Report an issue: GitHub.