BoundaryML/baml · error
failed to decode object handle: %w
Error message
failed to decode object handle: %w
What it means
Within a valid InvocationResponseSuccess, the result oneof must contain an Object carrying a raw object handle. If decodeRawObjectImpl fails to decode that object (bad handle bytes, unknown type id, runtime mismatch), the error is wrapped as 'failed to decode object handle' and delivered as the callback result.
Source
Thrown at engine/language_client_go/pkg/callbacks.go:248
callbackMutex.Lock()
defer callbackMutex.Unlock()
deleteCallback(id)
return
}
switch resp := response.GetResponse().(type) {
case *cffi.InvocationResponse_Error:
safeSend(callback.channel, ResultCallback{Error: BamlError{Message: resp.Error}})
case *cffi.InvocationResponse_Success:
success := resp.Success
if success == nil {
safeSend(callback.channel, ResultCallback{Error: fmt.Errorf("nil success in InvocationResponse")})
} else {
switch result := success.GetResult().(type) {
case *cffi.InvocationResponseSuccess_Object:
decoded, decodeErr := decodeRawObjectImpl(callback.runtime, result.Object)
if decodeErr != nil {
safeSend(callback.channel, ResultCallback{Error: fmt.Errorf("failed to decode object handle: %w", decodeErr)})
} else {
safeSend(callback.channel, ResultCallback{HasData: true, Data: decoded})
}
default:
safeSend(callback.channel, ResultCallback{Error: fmt.Errorf("unexpected result type in InvocationResponse: %T", success.GetResult())})
}
}
default:
safeSend(callback.channel, ResultCallback{Error: fmt.Errorf("unexpected response type in InvocationResponse")})
}
safeClose(callback.channel)
callbackMutex.Lock()
defer callbackMutex.Unlock()
deleteCallback(id)
}
func create_unique_id(ctx context.Context, onTick OnTickCallbackData) (uint32, chan ResultCallback) {View on GitHub (pinned to bd85ce9dee)
Solutions
- Read the wrapped decodeErr to see whether it's an unknown type or malformed handle bytes.
- Ensure the callback runtime (callback.runtime) is the same BamlRuntime instance that produced the object.
- Align BAML Go binding and native runtime versions.
- If using multiple runtimes, keep object handles scoped to the runtime that created them.
Example fix
// before handle, err := baml.BuildRequestFromC(otherRuntime, req) // object bound to otherRuntime // after handle, err := baml.BuildRequestFromC(currentRuntime, req) // use the same runtime instance
Defensive patterns
Strategy: type-guard
Try / catch
res := <-ch
if res.Error != nil {
if strings.Contains(res.Error.Error(), "failed to decode object handle") {
return fmt.Errorf("object handle unusable, recreate request with same runtime: %w", res.Error)
}
return res.Error
} Prevention
- Use one BamlRuntime instance per set of object handles
- Never share handles across runtime instances
- Keep runtime and Go bindings versions aligned
When it happens
Trigger: build_request_from_c (or similar) returns an InvocationResponseSuccess_Object whose Object payload cannot be decoded by decodeRawObjectImpl in the current runtime — e.g. handle created by a different runtime instance, corrupted bytes, or unsupported object type id.
Common situations: Sharing object handles across multiple BamlRuntime instances, mixing runtime versions, or the native side returning an object type the Go decoder doesn't know.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to decode object response: %w
- nil response
- failed to decode object at index %d: %w
- Protobuf decode error: {0}
- Map entry missing key
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/e7867ae02e179921.
Report an issue: GitHub.