{"record":{"id":"adc1784f8ed7b80d","repo":"BoundaryML/baml","slug":"enum-value-already-exists-in-enum","errorCode":null,"errorMessage":"Enum value already exists: {} in enum {}","messagePattern":"Enum value already exists: (.+?) in enum (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_cffi/src/raw_ptr_wrapper/type_builder/objects.rs","lineNumber":600,"sourceCode":"            }\n        };\n\n        EnumValueBuilder::new(\n            self.type_builder.clone(),\n            self.enum_name.clone(),\n            name.to_string(),\n        )\n        .mode(target_mode)\n    }\n\n    pub fn add_value(&self, rt: &BamlRuntime, value: &str) -> anyhow::Result<EnumValueBuilder> {\n        self.mode.at_least(NodeRW::ReadWrite)?;\n        let enm = self.enm(rt)?;\n\n        // if the IR already has the value, then its not valid to add it again\n        if let Ok(enm_ir) = rt.ir.find_enum(self.enum_name.as_str()) {\n            if enm_ir.find_value(value).is_some() {\n                anyhow::bail!(\n                    \"Enum value already exists: {} in enum {}\",\n                    value,\n                    self.enum_name\n                );\n            }\n        }\n\n        let builder = enm.lock().unwrap();\n        let _ = builder.upsert_value(value);\n        Ok(self.create_value(value, rt))\n    }\n\n    pub fn set_description(&self, rt: &BamlRuntime, description: &str) -> anyhow::Result<()> {\n        self.mode.at_least(NodeRW::LLMOnly)?;\n\n        let enm = self.enm(rt)?;\n        let builder = enm.lock().unwrap();\n        builder.with_meta(\"description\", BamlValue::String(description.to_string()));","sourceCodeStart":582,"sourceCodeEnd":618,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_cffi/src/raw_ptr_wrapper/type_builder/objects.rs#L582-L618","documentation":"Thrown by EnumBuilder::add_value() when the value you are trying to add is already declared on the enum in the compiled IR. The builder deliberately refuses duplicate additions: values coming from the AST are considered immutable, so re-adding them is treated as an invalid operation rather than a silent upsert.","triggerScenarios":"Calling tb.enum_(\"Color\").add_value(rt, \"red\") when 'red' is already a value of enum Color in the .baml file. Also happens when runtime patching code runs on every request and re-adds a value that the schema already defines.","commonSituations":" idempotency bugs where type-builder patches execute multiple times; copying example code that adds a value the sample schema already has; migration scripts that add values now present in the schema.","solutions":["Check the .baml enum definition and remove the add_value call for values already declared there.","Guard the call: only add the value if it's absent (e.g. track added values or catch this error and ignore it).","Move the value from runtime add_value calls into the .baml schema if it's static.","Ensure patch code runs once, not on every request/session setup."],"exampleFix":"// before\ntb.enum(\"Color\").add_value(rt, \"red\")?; // 'red' already in .baml\n// after\nif !declared_values.contains(\"red\") {\n    tb.enum(\"Color\").add_value(rt, \"red\")?;\n}","handlingStrategy":"validation","validationCode":"let already = rt.ir.find_enum(\"Color\")\n    .ok()\n    .map(|e| e.find_value(\"red\").is_some())\n    .unwrap_or(false);\nif !already {\n    tb.enum_(\"Color\").add_value(rt, \"red\")?;\n}","typeGuard":"fn ir_has_enum_value(rt: &BamlRuntime, enum_name: &str, value: &str) -> bool {\n    rt.ir.find_enum(enum_name).map(|e| e.find_value(value).is_some()).unwrap_or(false)\n}","tryCatchPattern":"match enum_builder.add_value(rt, \"red\") {\n    Err(e) if e.to_string().contains(\"already exists\") => { /* idempotent skip */ }\n    other => other?,\n}","preventionTips":["Guard every add_value with an IR existence check for idempotent patching.","Move static values into the .baml schema instead of adding them at runtime.","Make type-builder patches idempotent — they may run more than once."],"tags":["type-builder","baml","rust","duplicate-value"],"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-14T05:17:10.506Z"}