BoundaryML/baml · error · UDFConfigError

This config does not have any returns declared! At least one

Error message

This config does not have any returns declared! At least one return in one match path is required.

What it means

UDFConfig::validate enforces that the declared functions collectively declare at least one return across their match paths. A config whose functions have no returns anywhere cannot produce results, so validation fails with the NoReturnsDeclared variant carrying this message.

Source

Thrown at engine/boundary-udf/src/config.rs:74

/// Raw Jinja template which will be executed for the inputs that match.
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(transparent)]
pub struct OutputExpression(pub String);

#[derive(Debug, Deserialize, Serialize)]
pub struct UDFConfig {
    pub version: String,
    pub name: String,
    pub description: String,
    #[serde(rename = "constants")]
    #[serde(default)]
    pub global_constants: BamlMap<String, Constant>,
    pub functions: Vec<Function>,
}

#[derive(Debug, Error)]
pub enum UDFConfigError {
    #[error("This config does not have any returns declared! At least one return in one match path is required.")]
    NoReturnsDeclared,
}

impl UDFConfig {
    /// Verifies that the configuration is valid beyond deserialization format.
    /// Checked invariants:
    /// - At least one return is declared in the configuration: `gather_all_outputs` will return a
    ///   non-empty set.
    pub fn check(&self) -> Result<(), UDFConfigError> {
        fn find_returns(overrides: &[Function]) -> bool {
            for ov in overrides {
                if !ov.returns.is_empty() {
                    return true;
                }
            }

            overrides.iter().any(|f| find_returns(&f.overrides))
        }

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Add at least one return clause to one match path of at least one function in the config
  2. If the file is a work in progress, finish defining a return before validating/deploying the config
  3. If no functions are needed, remove the empty functions array or skip validation for placeholder configs

Example fix

// before
{ "functions": [{ "name": "f", "match": [{ "when": true }] }] }
// after
{ "functions": [{ "name": "f", "match": [{ "when": true, "return": "ok" }] }] }
Defensive patterns

Strategy: validation

Validate before calling

const cfg = JSON.parse(configJson);
const hasReturn = cfg.functions?.some(f =>
  (f.match ?? []).some(path => path.return !== undefined));
if (!hasReturn) throw new Error("config must declare at least one return in a match path");

Try / catch

match config.validate() { Ok(_) => ..., Err(UDFConfigError::NoReturnsDeclared) => eprintln!("add a return to at least one match path") }

Prevention

When it happens

Trigger: Deserializing a UDF config whose `functions` array is empty, or whose function definitions contain only match paths with no `return` clauses, then calling the validation method on UDFConfig.

Common situations: Hand-editing or generating boundary-udf JSON configs and omitting the returns section; a template/scaffold that created function skeletons without returns being validated as-is.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/acdb2905e0e0dbe5. Report an issue: GitHub.