BoundaryML/baml · error · ValueError

Enum with name already exists.

Error message

Enum with name {name} already exists.

What it means

TypeBuilder.add_class() also raises ValueError when the requested class name collides with an enum previously registered via add_enum() in the same builder. Class and enum names share one namespace in BAML dynamic types, so a class cannot shadow an existing enum name.

Solutions

  1. Rename one of the conflicting types (e.g. Status -> StatusEnum or StatusClass).
  2. Track registered names in one set in your code and check before either add_enum or add_class.
  3. Split type definitions across separate TypeBuilder instances if the namespace collision is intentional in different contexts.
  4. Fix the schema/source generator that emits colliding names.

Example fix

# before
tb.add_enum("Status")
tb.add_class("Status")  # ValueError: Class with name Status already exists (enum namespace)

# after
tb.add_enum("Status")
tb.add_class("StatusRecord")  # unique names
Defensive patterns

Strategy: validation

Validate before calling

used_names = set()
def register(tb, kind, name):
    if name in used_names:
        raise ValueError(f"{name} already registered")
    (tb.add_class if kind == "class" else tb.add_enum)(name)
    used_names.add(name)

Type guard

def name_is_free(tb, name: str) -> bool:
    classes = getattr(tb, "_TypeBuilder__classes", set())
    enums = getattr(tb, "_TypeBuilder__enums", set())
    return name not in classes and name not in enums

Try / catch

try:
    tb.add_class(name)
except ValueError as e:
    if "already exists" in str(e):
        tb.add_class(f"{name}Record")  # rename on collision
    else:
        raise

Prevention

When it happens

Trigger: Calling tb.add_enum("Status") followed by tb.add_class("Status") (or the reverse order) on the same TypeBuilder instance.

Common situations: Generating dynamic types from a schema where a class and an enum happen to share a name; merging type definitions from two modules into one builder; copy-pasted setup code adding both with the same identifier.

Related errors


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

Appendix: source

Thrown at engine/language_client_python/python_src/baml_py/type_builder.py:98

        return self._tb.bool()

    def list(self, inner: FieldType):
        return self._tb.list(inner)

    def null(self):
        return self._tb.null()

    def map(self, key: FieldType, value: FieldType):
        return self._tb.map(key, value)

    def union(self, types: typing.List[FieldType]):
        return self._tb.union(*types)

    def add_class(self, name: str) -> "NewClassBuilder":
        if name in self.__classes:
            raise ValueError(f"Class with name {name} already exists.")
        if name in self.__enums:
            raise ValueError(f"Enum with name {name} already exists.")
        self.__classes.add(name)
        return NewClassBuilder(self._tb, name)

    def add_enum(self, name: str) -> "NewEnumBuilder":
        if name in self.__classes:
            raise ValueError(f"Class with name {name} already exists.")
        if name in self.__enums:
            raise ValueError(f"Enum with name {name} already exists.")
        self.__enums.add(name)
        return NewEnumBuilder(self._tb, name)

    def add_baml(self, baml: str):
        return self._tb.add_baml(baml, self.__runtime)


class NewClassBuilder:
    def __init__(self, tb: _TypeBuilder, name: str):
        self.__bldr = tb.class_(name)

View on GitHub (pinned to bd85ce9dee)