BoundaryML/baml · error
nil success in InvocationResponse
Error message
nil success in InvocationResponse
What it means
After successfully unmarshaling an InvocationResponse, trigger_callback_object_handle expects the oneof response to carry a Success with a non-nil success payload. A Success case whose Success message pointer is nil violates the protocol contract, so the error is sent to the callback channel instead of a result.
Source
Thrown at engine/language_client_go/pkg/callbacks.go:242
func trigger_callback_object_handle(id uint32, callback CallbackData, content_bytes []byte) {
var response cffi.InvocationResponse
err := proto.Unmarshal(content_bytes, &response)
if err != nil {
safeSend(callback.channel, ResultCallback{Error: fmt.Errorf("failed to unmarshal InvocationResponse: %w", err)})
safeClose(callback.channel)
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)View on GitHub (pinned to bd85ce9dee)
Solutions
- Upgrade the BAML runtime and Go bindings to matching latest versions — this indicates an internal invariant break.
- Reproduce with a minimal call (e.g. build_request_from_c) and file an issue with the call and versions.
- Ensure no custom patched native library is in use that could construct malformed responses.
- Handle the ResultCallback.Error path gracefully in your callback consumer so the failure is visible.
Example fix
// before
res := <-callbackCh // res.Error: nil success in InvocationResponse
// after
if res.Error != nil {
log.Printf("baml callback failed: %v", res.Error) // surface and report with versions
return res.Error
} Defensive patterns
Strategy: try-catch
Try / catch
res := <-ch
if res.Error != nil {
if strings.Contains(res.Error.Error(), "nil success in InvocationResponse") {
log.Printf("baml internal protocol bug; versions: %s", baml.Version())
}
return res.Error
} Prevention
- Report occurrences with exact BAML versions — this is an internal invariant break
- Avoid custom-patched native runtimes
- Always branch on res.Error before using res.Data
When it happens
Trigger: The native side constructs an InvocationResponse with the Success case set but leaves the inner Success message nil — an internal bug in the Rust runtime, a protobuf default-construction mistake, or a wire round-trip that drops the nested message.
Common situations: Encountered during BAML internal protocol bugs or when a custom/patched runtime builds the response incorrectly; rarely caused by user code.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- failed to unmarshal content bytes: %w
- failed to marshal object method arguments: %w
- failed to unmarshal InvocationResponse: %w
- unexpected result type in InvocationResponse: %T
- unexpected response type in InvocationResponse
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/d8fba833e733b6d7.
Report an issue: GitHub.