BoundaryML/baml · error · Error

Property ${name} already exists.

Error message

Property ${name} already exists.

What it means

ClassBuilder.addProperty(name, type) throws when a property with the same name was already added to this builder, preventing duplicate fields in the generated class. The builder tracks names in a Set and rejects the second registration.

Source

Thrown at engine/language_client_typescript/type_builder.js:128

    }
    listProperties() {
        return Array.from(this.properties).map((name) => [name, new ClassPropertyViewer()]);
    }
    property(name) {
        if (!this.properties.has(name)) {
            throw new Error(`Property ${name} not found.`);
        }
        return new ClassPropertyViewer();
    }
}
exports.ClassViewer = ClassViewer;
class ClassBuilder extends ClassAst {
    constructor(tb, name, properties = new Set()) {
        super(tb, name, properties);
    }
    addProperty(name, type) {
        if (this.properties.has(name)) {
            throw new Error(`Property ${name} already exists.`);
        }
        this.properties.add(name);
        return new ClassPropertyBuilder(this.bldr.property(name).setType(type));
    }
    listProperties() {
        return this.bldr.listProperties().map(([name, prop]) => [name, new ClassPropertyBuilder(prop)]);
    }
    removeProperty(name) {
        this.properties.delete(name);
        this.bldr.removeProperty(name);
    }
    reset() {
        this.bldr.reset();
    }
    property(name) {
        if (!this.properties.has(name)) {
            throw new Error(`Property ${name} not found.`);
        }

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Skip the add if the property already exists, or rebuild the class with corrected types
  2. Deduplicate source keys (e.g. Object.entries on a merged object is already unique — check your iteration logic)
  3. Use a fresh ClassBuilder when the schema changes instead of mutating in place
  4. Wrap addProperty in try/catch to ignore intentional duplicates

Example fix

// before
cb.addProperty("id", "string");
cb.addProperty("id", "int"); // throws
// after
cb.addProperty("id", "int"); // decide one type; duplicates not allowed
Defensive patterns

Strategy: validation

Validate before calling

const seenProps = new Set();
function addPropOnce(cb, name, type) { if (!seenProps.has(name)) { seenProps.add(name); cb.addProperty(name, type); } }

Type guard

null

Try / catch

try { cb.addProperty(name, type); } catch (e) {
  if (String(e.message).includes('already exists')) { /* skip or rebuild */ }
  else throw e;
}

Prevention

When it happens

Trigger: Calling addProperty("x", ...) twice on the same ClassBuilder; loops that add properties from data containing duplicate keys; re-running builder construction on a retained builder instance.

Common situations: Building classes from JSON samples where keys repeat across merged objects; hot-reload re-running schema setup; overwriting a field's type by re-adding it (not supported — must rebuild).

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