BoundaryML/baml · error

Enum value not found: {} in enum {}

Error message

Enum value not found: {} in enum {}

What it means

Thrown by EnumBuilder::value() when the enum exists in the runtime IR but the requested value name is not among its IR-declared values. The method upserts the value only if the IR already contains it; otherwise it refuses, keeping IR-defined enums consistent.

Source

Thrown at engine/language_client_cffi/src/raw_ptr_wrapper/type_builder/objects.rs:719

            .collect())
    }

    pub fn value(&self, rt: &BamlRuntime, name: &str) -> anyhow::Result<EnumValueBuilder> {
        self.mode.at_least(NodeRW::ReadOnly)?;
        let enm = self.enm(rt)?;

        let builder = enm.lock().unwrap();
        let values = builder.list_values();
        if values.contains(&name.to_string()) {
            Ok(self.create_value(name, rt))
        } else {
            // if the IR has the value, then its valid to add it again
            if let Ok(enm_ir) = rt.ir.find_enum(self.enum_name.as_str()) {
                if enm_ir.find_value(name).is_some() {
                    let _ = builder.upsert_value(name);
                    Ok(self.create_value(name, rt))
                } else {
                    anyhow::bail!("Enum value not found: {} in enum {}", name, self.enum_name)
                }
            } else {
                anyhow::bail!("Enum value not found: {} in enum {}", name, self.enum_name)
            }
        }
    }

    pub fn is_from_ast(&self, rt: &BamlRuntime) -> anyhow::Result<bool> {
        self.mode.at_least(NodeRW::ReadOnly)?;
        Ok(rt.ir.find_enum(self.enum_name.as_str()).is_ok())
    }
}

#[derive(Debug, Clone)]
pub struct EnumValueBuilder {
    type_builder: RuntimeTypeBuilder,
    enum_name: String,
    pub value_name: String,

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Fix the value name to match the .baml enum definition.
  2. Add the value first with EnumBuilder::add_value if it's a dynamic extension.
  3. Check the schema for renames of the enum value.
  4. Verify the same TypeBuilder instance was used for the prior add_value.

Example fix

// before
let v = tb.enum("Color").value(rt, "purpl")?;
// after
let v = tb.enum("Color").value(rt, "purple")?;
Defensive patterns

Strategy: validation

Validate before calling

let ok = rt.ir.find_enum("Color")
    .ok()
    .map(|e| e.find_value("purple").is_some())
    .unwrap_or(false);
if !ok { /* add_value first or fix the name */ }

Type guard

fn ir_enum_has_value(rt: &BamlRuntime, enum_name: &str, value: &str) -> bool {
    rt.ir.find_enum(enum_name).map(|e| e.find_value(value).is_some()).unwrap_or(false)
}

Try / catch

match enum_builder.value(rt, "purple") {
    Err(e) if e.to_string().contains("Enum value not found") => add_value_then_retry()?,
    other => other,
}

Prevention

When it happens

Trigger: Calling tb.enum_("Color").value(rt, "purple") where Color is defined in .baml but has no 'purple' value, and 'purple' was never added via add_value on the builder.

Common situations: typos in value names; accessing a value that was renamed in the schema; reading a value added at runtime on a different TypeBuilder instance; assuming add_value succeeded when it actually failed.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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