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
- Rename one of the conflicting types (e.g. Status -> StatusEnum or StatusClass).
- Track registered names in one set in your code and check before either add_enum or add_class.
- Split type definitions across separate TypeBuilder instances if the namespace collision is intentional in different contexts.
- 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
- Remember classes and enums share one namespace in a TypeBuilder
- Validate schema-derived names for collisions before registering
- Register every type through one helper that owns a used-names set
- Suffix generated names (e.g. Enum/Record) to avoid natural collisions
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
- Class with name already exists.
- Enum already exists
- Value already exists.
- Value not found.
- attempted to read a property that has no defined type, this…
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)