BoundaryML/baml · error

failed to get usage: %w

Error message

failed to get usage: %w

What it means

Collector.Usage() calls the runtime's `usage` method over FFI and wraps any CallMethod failure as "failed to get usage: %w". This is a generic wrapper: the underlying error (unwrapped via errors.Unwrap) carries the real cause — an FFI transport failure, a runtime-side exception in the usage method, or an object-lifetime problem. It indicates the usage data could not be retrieved from the collector's runtime object at all.

Source

Thrown at engine/language_client_go/pkg/rawobjects_collector.go:30

	*raw_objects.RawObject
}

func newCollector(ptr int64, rt unsafe.Pointer) Collector {
	return &collector{raw_objects.FromPointer(ptr, rt)}
}

func (c *collector) ObjectType() cffi.BamlObjectType {
	return cffi.BamlObjectType_OBJECT_COLLECTOR
}

func (c *collector) pointer() int64 {
	return c.RawObject.Pointer()
}

func (c *collector) Usage() (Usage, error) {
	result, err := raw_objects.CallMethod(c, "usage", nil)
	if err != nil {
		return nil, fmt.Errorf("failed to get usage: %w", err)
	}

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

	return usage, nil
}

func (c *collector) Name() (string, error) {
	result, err := raw_objects.CallMethod(c, "name", nil)
	if err != nil {
		return "", fmt.Errorf("failed to get name: %w", err)
	}

	name, ok := result.(string)
	if !ok {

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Read the wrapped cause with %v/errors.Unwrap(err) to identify the actual failure before changing code.
  2. Ensure the Collector is used only while the BAML runtime is alive in the same process; recreate the collector if the runtime restarted.
  3. Check for concurrent use of the collector from multiple goroutines and add synchronization.
  4. Retry the call once to rule out a transient FFI hiccup, then investigate runtime logs if it persists.

Example fix

// before
usage, err := collector.Usage()
// after
usage, err := collector.Usage()
if err != nil {
    return nil, fmt.Errorf("usage unavailable: %v (cause: %v)", err, errors.Unwrap(err))
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the collector is still tracked by the runtime:
// if collector == nil { return errors.New("collector is nil") }

Type guard

func hasValidCollector(c baml.Collector) bool { return c != nil }

Try / catch

usage, err := collector.Usage()
if err != nil {
    var retryable = strings.Contains(err.Error(), "failed to get usage")
    if retryable {
        time.Sleep(100 * time.Millisecond)
        usage, err = collector.Usage()
    }
    if err != nil {
        return nil, fmt.Errorf("usage unavailable: %w", err)
    }
}

Prevention

When it happens

Trigger: Calling collector.Usage() when CallMethod fails: the collector's runtime object was already freed/GC'd, the runtime returned an exception, or the FFI bridge errored before a result could be decoded.

Common situations: Holding a Collector across a runtime shutdown or process boundary; calling Usage after Clear or after the BAML runtime was torn down; concurrency issues where the collector pointer becomes invalid.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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