BoundaryML/baml · error · ValueError

Value already exists.

Error message

Value {name} already exists.

What it means

Python type-builder validation: add_value was called with an enum value name that is already registered in this NewEnumBuilder. The builder tracks names in a set to keep enums well-formed (duplicate variants would collide in codegen), so the second registration of the same name is rejected.

Solutions

  1. Track added value names in a set and skip duplicates before add_value
  2. Use a fresh TypeBuilder/enum builder per registration pass
  3. Catch ValueError and treat 'already exists' as a no-op

Example fix

// before
for v in values:
    enum_b.add_value(v)
// after
seen = set()
for v in values:
    if v not in seen:
        enum_b.add_value(v)
        seen.add(v)
Defensive patterns

Strategy: validation

Validate before calling

names = {n for n, _ in enum_b.list_values()}
for v in values:
    if v not in names:
        enum_b.add_value(v)

Try / catch

try:
    enum_b.add_value(name)
except ValueError as e:
    if "already exists" not in str(e):
        raise

Prevention

When it happens

Trigger: Calling enum_builder.add_value('RED') twice on the same NewEnumBuilder instance; re-running value-registration code against a reused builder.

Common situations: Idempotency attempts when building enums dynamically; loops over config lists containing duplicate entries; re-running a script without rebuilding the TypeBuilder.

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/0e05623fcf6c0395. Report an issue: GitHub.

Appendix: source

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

class NewEnumBuilder:
    def __init__(self, tb: _TypeBuilder, name: str):
        self.__bldr = tb.enum(name)
        self.__values: typing.Set[str] = set()
        self.__vals = NewEnumValues(self.__bldr, self.__values)

    def type(self) -> FieldType:
        return self.__bldr.field()

    @property
    def values(self) -> "NewEnumValues":
        return self.__vals

    def list_values(self) -> typing.List[typing.Tuple[str, EnumValueBuilder]]:
        return [(name, self.__bldr.value(name)) for name in self.__values]

    def add_value(self, name: str) -> "EnumValueBuilder":
        if name in self.__values:
            raise ValueError(f"Value {name} already exists.")
        self.__values.add(name)
        # NOTE(sam): why is this inconsistent between classes and enums?
        return self.__bldr.value(name)


class NewEnumValues:
    def __init__(self, enum_bldr: EnumBuilder, values: typing.Set[str]):
        self.__bldr = enum_bldr
        self.__values = values

    def __getattr__(self, name: str) -> "EnumValueBuilder":
        if name not in self.__values:
            raise AttributeError(f"Value {name} not found.")
        return self.__bldr.value(name)


class EnumValueViewer:
    def __init__(self, bldr: "EnumValueBuilder"):

View on GitHub (pinned to bd85ce9dee)