BoundaryML/baml · error

unexpected type for ID: %T

Error message

unexpected type for ID: %T

What it means

This error is returned by the Id() accessor on a BAML FunctionLog object. The library fetched the 'id' attribute of the underlying function-log object via its Rust runtime over the C FFI (raw_objects.CallMethod), and the returned value was not a Go string. This indicates the runtime returned a value whose Go representation does not match the expected type, typically meaning the runtime object is corrupt, the pointer is stale (object already destroyed), or an internal decoder bug.

Source

Thrown at engine/language_client_go/pkg/rawobjects_function_log.go:35

}

func (f *functionLog) ObjectType() cffi.BamlObjectType {
	return cffi.BamlObjectType_OBJECT_FUNCTION_LOG
}

func (f *functionLog) pointer() int64 {
	return f.RawObject.Pointer()
}

func (f *functionLog) Id() (string, error) {
	result, err := raw_objects.CallMethod(f, "id", nil)
	if err != nil {
		return "", fmt.Errorf("failed to get ID: %w", err)
	}

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

	return id, nil
}

func (f *functionLog) FunctionName() (string, error) {
	result, err := raw_objects.CallMethod(f, "function_name", nil)
	if err != nil {
		return "", fmt.Errorf("failed to get function name: %w", err)
	}

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

	return name, nil
}

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Do not use the FunctionLog after its owning function call/stream has finished and been consumed; obtain the log and read Id() within the same iteration/callback.
  2. Print the wrapped inner error (fmt.Errorf %w chain) to see the underlying CallMethod failure ('failed to call object method function', 'failed to decode object response', etc.).
  3. Verify the Go client version (engine/language_client_go) matches the BAML runtime/CLI version generating the logs; regenerate the client with `baml init`/`baml generate`.
  4. If reproducible with a valid, live object, file a bug with the %T value printed by the error (it names the actual Go type returned).

Example fix

// before
id, err := fnLog.Id()
if err != nil {
    return fmt.Errorf("getting id: %w", err)
}
// after
id, err := fnLog.Id()
if err != nil {
    return fmt.Errorf("getting id (log may already be consumed/freed): %w", err)
}
Defensive patterns

Strategy: type-guard

Validate before calling

if fnLog == nil {
    return errors.New("function log is nil; cannot read Id")
}

Type guard

func idIsString(v any) (string, bool) {
    s, ok := v.(string)
    return s, ok
}

Try / catch

id, err := fnLog.Id()
if err != nil {
    if strings.Contains(err.Error(), "unexpected type for ID") {
        // runtime returned a non-string; treat the log object as invalid
        return fmt.Errorf("function log id unavailable (stale object?): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Id() on a functionLog whose underlying BAML runtime object has been released or whose 'id' attribute decodes to a non-string cffi value (e.g. a class/map/object instead of a string).

Common situations: Holding a FunctionLog reference after the function stream completed and the runtime freed the object; running a mismatched baml Go client against an older/newer BAML runtime that changed the id field's representation; internal decodeObjectResponse returning an unexpected variant.

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