{"record":{"id":"d90b07e16aff70b3","repo":"BoundaryML/baml","slug":"value-name-already-exists-d90b07","errorCode":null,"errorMessage":"Value ${name} already exists.","messagePattern":"Value (.+?) already exists\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"engine/language_client_typescript/typescript_src/type_builder.ts","lineNumber":289,"sourceCode":"    if (!this.values.has(name)) {\n      throw new Error(`Value ${name} not found.`)\n    }\n    return new EnumValueViewer()\n  }\n}\n\nexport class EnumValueViewer {\n  constructor() {}\n}\n\nexport class EnumBuilder<EnumName extends string, T extends string = string> extends EnumAst<EnumName, T> {\n  constructor(tb: _TypeBuilder, name: EnumName, values: Set<T | string> = new Set()) {\n    super(tb, name, values)\n  }\n\n  addValue<S extends string>(name: RestrictNot<EnumName, S, T>): EnumValueBuilder {\n    if (this.values.has(name)) {\n      throw new Error(`Value ${name} already exists.`)\n    }\n    this.values.add(name)\n    return this.bldr.value(name)\n  }\n\n  listValues(): Array<[string, EnumValueBuilder]> {\n    return Array.from(this.values).map((name) => [name, this.bldr.value(name)])\n  }\n\n  value(name: string): EnumValueBuilder {\n    return this.bldr.value(name)\n  }\n}\n","sourceCodeStart":271,"sourceCodeEnd":303,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_typescript/typescript_src/type_builder.ts#L271-L303","documentation":"EnumValueBuilder.addValue throws this when the enum already contains a value with the given name. The builder guards against duplicate enum members because BAML enums require unique value names; adding the same name twice would produce an invalid enum definition. It is a deliberate programmer-error guard, not a runtime condition.","triggerScenarios":"Calling addValue(name) on an EnumValueBuilder whose underlying values Set already contains name. This happens when the same value name is added twice in a builder chain, or when a loop/config list feeding addValue contains duplicates, or when addValue is called for a name that was passed into the TypeBuilder enum constructor's initial values Set.","commonSituations":"Building BAML enums dynamically from config files or database rows that contain duplicate entries; merging enum values from two sources without deduplicating; copy-pasted builder code that adds the same literal twice; hot-reload code that re-adds values onto an existing builder without resetting it.","solutions":["Deduplicate the source list before calling addValue, e.g. [...new Set(names)]","Guard each call with a membership check or wrap it in try/catch and skip existing values","Rebuild the TypeBuilder/enum from scratch instead of re-adding values to an existing builder","If the duplicate is intentional (same semantic value from two sources), normalize the source data upstream"],"exampleFix":"// before\nfor (const v of configValues) {\n  enumBuilder.addValue(v.name);\n}\n// after\nfor (const v of [...new Set(configValues)]) {\n  if (!enumBuilder.listValues().some(([n]) => n === v.name)) {\n    enumBuilder.addValue(v.name);\n  }\n}","handlingStrategy":"validation","validationCode":"if (enumBuilder.listValues().some(([existing]) => existing === newName)) {\n  throw new Error(`Cannot add duplicate enum value: ${newName}`);\n}\nenumBuilder.addValue(newName);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deduplicate name lists ([...new Set(names)]) before feeding addValue","Build enums from scratch on each rebuild instead of mutating a shared builder","Centralize enum construction in one function so adds are traceable"],"tags":["typescript","enum","duplicate-value","builder"],"backgroundTag":"file-already-exists","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}