BoundaryML/baml · error

unexpected type for string type: %T

Error message

unexpected type for string type: %T

What it means

typeBuilder.String() calls the FFI method "string" on the TypeBuilder and asserts the result implements the baml Type interface. If the bridge returns something else (a raw pointer that was not wrapped into a Type, nil, etc.), the assertion fails and this error is thrown. It indicates the CFFI object decoder failed to produce a proper Type wrapper for the built type.

Solutions

  1. Check the %T in the message: if it is a raw pointer type, your bindings cannot wrap this object - update the baml Go module.
  2. Ensure TypeBuilder comes from the same baml runtime version as the bindings you compile against.
  3. Rebuild/refresh generated cffi code (go mod tidy + upgrade) if the type registry is stale.
  4. Report the missing Type wrapper to boundaryml/baml if versions are aligned.

Example fix

// before
typ, err := tb.String()
if err != nil {
    return err
}

// after: retry with a freshly created TypeBuilder from the same runtime
newTB, err := rt.TypeBuilder()
if err != nil {
    return err
}
typ, err := newTB.String()
if err != nil {
    return fmt.Errorf("string type build failed: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if tb == nil {
    return errors.New("type builder is nil")
}

Type guard

func isBamlType(v any) bool { _, ok := v.(baml.Type); return ok }

Try / catch

typ, err := tb.String()
if err != nil {
    if strings.Contains(err.Error(), "unexpected type for string type") {
        return fmt.Errorf("baml bindings/runtime version mismatch: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling TypeBuilder.String() (in type-builder based schema construction, e.g. dynamic BAML types) when the underlying "string" method returns an unwrapped RawPointer or nil instead of a Type implementation.

Common situations: Go bindings out of sync with the native runtime so new type objects are not recognized by the wrapper registry; calling String() on a TypeBuilder obtained from an incompatible runtime; internal decoder registry missing the OBJECT_* mapping.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at engine/language_client_go/pkg/rawobjects_type_builder.go:33

func (tb *typeBuilder) ObjectType() cffi.BamlObjectType {
	return cffi.BamlObjectType_OBJECT_TYPE_BUILDER
}

func newTypeBuilder(ptr int64, rt unsafe.Pointer) TypeBuilder {
	return &typeBuilder{raw_objects.FromPointer(ptr, rt)}
}

// Basic types
func (tb *typeBuilder) String() (Type, error) {
	result, err := raw_objects.CallMethod(tb, "string", nil)
	if err != nil {
		return nil, err
	}

	typ, ok := result.(Type)
	if !ok {
		return nil, fmt.Errorf("unexpected type for string type: %T", result)
	}

	return typ, nil
}

func (tb *typeBuilder) Int() (Type, error) {
	result, err := raw_objects.CallMethod(tb, "int", nil)
	if err != nil {
		return nil, err
	}

	typ, ok := result.(Type)
	if !ok {
		return nil, fmt.Errorf("unexpected type for int type: %T", result)
	}

	return typ, nil
}

View on GitHub (pinned to bd85ce9dee)