BoundaryML/baml · error

unexpected type for start time: %T

Error message

unexpected type for start time: %T

What it means

After the FFI call "start_time_utc_ms" succeeds, StartTimeUTCMs() asserts the returned any is a Go int64. If the bridge decoded the timestamp into any other Go type (e.g. float64, uint64, or a pointer), the assertion fails and this error is thrown. It is an internal contract violation between the CFFI bridge decoder and this wrapper, not something the caller controls.

Solutions

  1. Read the %T in the error message to see which Go type the bridge returned; that reveals the encoding drift.
  2. Upgrade or downgrade the baml Go module so bindings and native runtime use the same FFI encoding (int64 timestamps).
  3. If you cannot change versions, wrap access and convert the alternate numeric type yourself after reflect-based inspection.
  4. Report the decoder bug to boundaryml/baml if versions are aligned and the error persists.

Example fix

// before (library-level assumption)
startTime, ok := result.(int64)

// after (caller-side tolerant wrapper)
func startMs(t baml.Timing) (int64, error) {
    v, err := t.StartTimeUTCMs()
    if err != nil {
        return 0, err
    }
    return v, nil
}
Defensive patterns

Strategy: type-guard

Type guard

func isInt64(v any) bool { _, ok := v.(int64); return ok }

Try / catch

startMs, err := timing.StartTimeUTCMs()
if err != nil {
    if strings.Contains(err.Error(), "unexpected type for start time") {
        log.Printf("FFI encoding drift on start_time_utc_ms: %v", err)
        return 0, nil
    }
    return 0, err
}

Prevention

When it happens

Trigger: Calling StartTimeUTCMs() when the bridge's "start_time_utc_ms" method returns a non-int64 value (e.g. float64 or uint64 from a changed native encoding).

Common situations: Go binding version out of sync with the native BAML runtime so the timestamp is now encoded as a different integer/float type; custom or older cffi decoders.

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

Appendix: source

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

}

func (t *timing) ObjectType() cffi.BamlObjectType {
	return cffi.BamlObjectType_OBJECT_TIMING
}

func (t *timing) pointer() int64 {
	return t.RawObject.Pointer()
}

func (t *timing) StartTimeUTCMs() (int64, error) {
	result, err := raw_objects.CallMethod(t, "start_time_utc_ms", nil)
	if err != nil {
		return 0, fmt.Errorf("failed to get start time: %w", err)
	}

	startTime, ok := result.(int64)
	if !ok {
		return 0, fmt.Errorf("unexpected type for start time: %T", result)
	}

	return startTime, nil
}

func (t *timing) DurationMs() (*int64, error) {
	result, err := raw_objects.CallMethod(t, "duration_ms", nil)
	if err != nil {
		return nil, fmt.Errorf("failed to get duration: %w", err)
	}

	if result == nil {
		return nil, nil
	}

	duration, ok := result.(int64)
	if !ok {
		return nil, fmt.Errorf("unexpected type for duration: %T", result)

View on GitHub (pinned to bd85ce9dee)