{"record":{"id":"d8fba833e733b6d7","repo":"BoundaryML/baml","slug":"nil-success-in-invocationresponse","errorCode":null,"errorMessage":"nil success in InvocationResponse","messagePattern":"nil success in InvocationResponse","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/language_client_go/pkg/callbacks.go","lineNumber":242,"sourceCode":"func trigger_callback_object_handle(id uint32, callback CallbackData, content_bytes []byte) {\n\tvar response cffi.InvocationResponse\n\terr := proto.Unmarshal(content_bytes, &response)\n\tif err != nil {\n\t\tsafeSend(callback.channel, ResultCallback{Error: fmt.Errorf(\"failed to unmarshal InvocationResponse: %w\", err)})\n\t\tsafeClose(callback.channel)\n\t\tcallbackMutex.Lock()\n\t\tdefer callbackMutex.Unlock()\n\t\tdeleteCallback(id)\n\t\treturn\n\t}\n\n\tswitch resp := response.GetResponse().(type) {\n\tcase *cffi.InvocationResponse_Error:\n\t\tsafeSend(callback.channel, ResultCallback{Error: BamlError{Message: resp.Error}})\n\tcase *cffi.InvocationResponse_Success:\n\t\tsuccess := resp.Success\n\t\tif success == nil {\n\t\t\tsafeSend(callback.channel, ResultCallback{Error: fmt.Errorf(\"nil success in InvocationResponse\")})\n\t\t} else {\n\t\t\tswitch result := success.GetResult().(type) {\n\t\t\tcase *cffi.InvocationResponseSuccess_Object:\n\t\t\t\tdecoded, decodeErr := decodeRawObjectImpl(callback.runtime, result.Object)\n\t\t\t\tif decodeErr != nil {\n\t\t\t\t\tsafeSend(callback.channel, ResultCallback{Error: fmt.Errorf(\"failed to decode object handle: %w\", decodeErr)})\n\t\t\t\t} else {\n\t\t\t\t\tsafeSend(callback.channel, ResultCallback{HasData: true, Data: decoded})\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tsafeSend(callback.channel, ResultCallback{Error: fmt.Errorf(\"unexpected result type in InvocationResponse: %T\", success.GetResult())})\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tsafeSend(callback.channel, ResultCallback{Error: fmt.Errorf(\"unexpected response type in InvocationResponse\")})\n\t}\n\n\tsafeClose(callback.channel)","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/language_client_go/pkg/callbacks.go#L224-L260","documentation":"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.","triggerScenarios":"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.","commonSituations":"Encountered during BAML internal protocol bugs or when a custom/patched runtime builds the response incorrectly; rarely caused by user code.","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."],"exampleFix":"// before\nres := <-callbackCh // res.Error: nil success in InvocationResponse\n\n// after\nif res.Error != nil {\n    log.Printf(\"baml callback failed: %v\", res.Error) // surface and report with versions\n    return res.Error\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"res := <-ch\nif res.Error != nil {\n\tif strings.Contains(res.Error.Error(), \"nil success in InvocationResponse\") {\n\t\tlog.Printf(\"baml internal protocol bug; versions: %s\", baml.Version())\n\t}\n\treturn res.Error\n}","preventionTips":["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"],"tags":["go","protobuf","ffi","internal"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}