BoundaryML/baml · error

unexpected type for class property builder: %T

Error message

unexpected type for class property builder: %T

What it means

ClassBuilder.AddProperty() invokes the runtime's `add_property` method over FFI and asserts the returned value is a ClassPropertyBuilder. When the runtime returns any other Go type (nil, a raw pointer, a string, etc.), the assertion fails and this error is returned. It means the FFI call did not honor the expected return contract, usually due to a bindings/runtime version mismatch or an upstream failure that degraded the result.

Source

Thrown at engine/language_client_go/pkg/rawobjects_class_builder.go:75

	}

	return rawObjectsCast, nil
}

// AddProperty adds a new property to the class
func (cb *classBuilder) AddProperty(name string, fieldType Type) (ClassPropertyBuilder, error) {
	args := map[string]interface{}{
		"name":       name,
		"field_type": fieldType,
	}
	result, err := raw_objects.CallMethod(cb, "add_property", args)
	if err != nil {
		return nil, err
	}

	classPropertyBuilder, ok := result.(ClassPropertyBuilder)
	if !ok {
		return nil, fmt.Errorf("unexpected type for class property builder: %T", result)
	}

	return classPropertyBuilder, nil
}

// Property gets a specific property from the class
func (cb *classBuilder) Property(name string) (ClassPropertyBuilder, error) {
	args := map[string]interface{}{
		"name": name,
	}
	result, err := raw_objects.CallMethod(cb, "property", args)
	if err != nil {
		return nil, err
	}

	classPropertyBuilder, ok := result.(ClassPropertyBuilder)
	if !ok {
		return nil, fmt.Errorf("unexpected type for class property builder: %T", result)

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Ensure the Go bindings and BAML runtime versions match exactly; upgrade both together.
  2. Log the %T value from the error and check whether it is nil, indicating the runtime returned nothing — inspect the add_property call arguments.
  3. Retry the operation with a freshly constructed ClassBuilder in case the object's runtime state is corrupt.
  4. Report to BAML maintainers with the error text if versions match.

Example fix

// before (caller, unguarded)
prop, err := classBuilder.AddProperty("score", myType)
// after
prop, err := classBuilder.AddProperty("score", myType)
if err != nil {
    return nil, fmt.Errorf("AddProperty failed, check baml runtime/binding version parity: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure fieldType came from the same runtime before calling:
// if fieldType == nil { return errors.New("fieldType required") }

Type guard

func isClassPropertyBuilder(result any) bool {
    _, ok := result.(ClassPropertyBuilder)
    return ok
}

Try / catch

prop, err := classBuilder.AddProperty(name, fieldType)
if err != nil {
    if strings.Contains(err.Error(), "unexpected type for class property builder") {
        return nil, fmt.Errorf("AddProperty FFI contract violation (check version parity): %w", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling AddProperty(name, fieldType) on a class builder when CallMethod returns a non-ClassPropertyBuilder value — e.g. nil after a failed mutation, or a wrong object type because the property name/field_type arguments were rejected upstream without raising.

Common situations: Building dynamic classes with a Go client and native runtime built from different commits; passing a Type object that the runtime could not resolve, causing a fallback result; a stale shared library after upgrading BAML.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/6a3f30f8d7ada072. Report an issue: GitHub.