BoundaryML/baml · error

Property already exists: {} in class {}

Error message

Property already exists: {} in class {}

What it means

ClassBuilder::add_property refuses to add a property that already exists in the IR's class definition. BAML requires unique property names within a class, so re-adding an existing field bails instead of overwriting it.

Source

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

            .get_meta("description")
            .and_then(|value| value.as_str().map(|s| s.to_string()))
            .or_else(ast_description);
        Ok(result)
    }

    pub fn add_property(
        &self,
        rt: &BamlRuntime,
        name: &str,
        field_type: TypeIR,
    ) -> anyhow::Result<ClassPropertyBuilder> {
        self.mode.at_least(NodeRW::ReadWrite)?;
        let cls = self.cls(rt)?;

        // if the IR already has the property, then its not valid to add it again
        if let Ok(cls) = rt.ir.find_class(self.class_name.as_str()) {
            if cls.find_field(name).is_some() {
                anyhow::bail!(
                    "Property already exists: {} in class {}",
                    name,
                    self.class_name
                );
            }
        }

        let builder = cls.lock().unwrap();
        let prop = builder.upsert_property(name);
        prop.lock().unwrap().set_type(field_type);
        Ok(self.create_property(name, rt))
    }

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

        let builder = cls.lock().unwrap();

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Use cb.property(rt, name) to fetch/modify the existing property instead of add_property
  2. Check for existing fields before calling add_property (e.g. via list_properties)
  3. Rename the new property if you truly need an additional field

Example fix

// before
cb.add_property(rt, "name", tb.string_type())?; // fails if 'name' exists
// after
if !cb.list_properties(rt)?.contains_key("name") {
    cb.add_property(rt, "name", tb.string_type())?;
}
Defensive patterns

Strategy: validation

Validate before calling

# check before add
props = cb.list_properties(rt)
if "name" not in props:
    cb.add_property(rt, "name", tb.string())

Try / catch

try:
    cb.add_property(rt, name, ty)
except Exception as e:
    if "already exists" in str(e):
        p = cb.property(rt, name)
    else:
        raise

Prevention

When it happens

Trigger: Calling cb.add_property(rt, "name", ...) when the class already defines a field 'name' in the BAML source (cls.find_field succeeds).

Common situations: Dynamically adding a property that is already declared in the .baml class; re-running non-idempotent builder code that re-adds the same property.

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


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