BoundaryML/baml · error
Enum with name {name} already exists
Error message
Enum with name {name} already exists What it means
TypeBuilder::add_enum refuses to create an enum whose name is already defined in the runtime IR. BAML treats enum names as unique; adding a duplicate would create an ambiguous schema, so the call bails instead.
Source
Thrown at engine/language_client_cffi/src/raw_ptr_wrapper/type_builder/objects.rs:61
assert!(NodeRW::LLMOnly.at_least(NodeRW::LLMOnly).is_ok());
assert!(NodeRW::LLMOnly.at_least(NodeRW::ReadWrite).is_err());
assert!(NodeRW::ReadWrite.at_least(NodeRW::ReadOnly).is_ok());
assert!(NodeRW::ReadWrite.at_least(NodeRW::LLMOnly).is_ok());
assert!(NodeRW::ReadWrite.at_least(NodeRW::ReadWrite).is_ok());
}
}
#[derive(Debug, Clone, Default)]
pub struct TypeBuilder {
pub type_builder: RuntimeTypeBuilder,
}
impl TypeBuilder {
pub fn add_enum(&self, rt: &BamlRuntime, name: &str) -> anyhow::Result<EnumBuilder> {
match rt.ir.find_enum(name) {
Ok(_) => {
anyhow::bail!("Enum with name {name} already exists");
}
Err(_) => {
let _ = self.type_builder.upsert_enum(name);
let builder = EnumBuilder::new(self.type_builder.clone(), name.to_string());
Ok(builder.mode(NodeRW::ReadWrite))
}
}
}
pub fn add_class(&self, rt: &BamlRuntime, name: &str) -> anyhow::Result<ClassBuilder> {
match rt.ir.find_class(name) {
Ok(_) => {
anyhow::bail!("Class with name {name} already exists");
}
Err(_) => {
let _ = self.type_builder.upsert_class(name);
let builder = ClassBuilder::new(self.type_builder.clone(), name.to_string());
Ok(builder.mode(NodeRW::ReadWrite))View on GitHub (pinned to bd85ce9dee)
Solutions
- Use tb.r#enum(rt, name) to fetch and modify the existing enum instead of add_enum
- Check existence first (match rt.ir / wrap in a check) and only call add_enum for new names
- Rename the new enum to avoid the collision
Example fix
// before
let eb = tb.add_enum(rt, "Color")?; // fails if Color exists
// after
let eb = match tb.r#enum(rt, "Color") {
Ok(eb) => eb,
Err(_) => tb.add_enum(rt, "Color")?,
}; Defensive patterns
Strategy: try-catch
Validate before calling
# caller side: check before add
if enum_exists(rt, "Color"):
eb = tb.enum("Color")
else:
eb = tb.add_enum(rt, "Color") Try / catch
try:
eb = tb.add_enum(rt, name)
except Exception as e:
if "already exists" in str(e):
eb = tb.enum(name)
else:
raise Prevention
- Make TypeBuilder setup idempotent: fetch-if-exists, add-if-missing
- Keep dynamic enum names in one registry to detect collisions
- Compare against enum names declared in .baml files before adding
When it happens
Trigger: Calling tb.add_enum(rt, "Name") when an enum named 'Name' already exists in the BAML source the runtime was compiled from, or when add_enum was already called for that name.
Common situations: Dynamically adding an enum that duplicates one declared in .baml files; re-running builder setup code without idempotency checks; name collisions between dynamic enums and statically-declared ones.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Class with name {name} already exists
- Enum with name {name} does not exist
- Class ${name} already exists
- Property ${name} already exists.
- Enum '{0}' not found
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/fa4c928c74876d0a.
Report an issue: GitHub.