{"record":{"id":"e85f7e111c02358c","repo":"dotnet/reactive","slug":"the-asynchronous-operation-completed-unexpectedly-e85f7e","errorCode":null,"errorMessage":"The asynchronous operation completed unexpectedly.","messagePattern":"The asynchronous operation completed unexpectedly\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive.WindowsRuntime/AsyncInfoToObservableBridge.cs","lineNumber":64,"sourceCode":"            switch (status)\n            {\n                case AsyncStatus.Error:\n                    error = info.ErrorCode ?? throw new InvalidOperationException(\"The asynchronous operation failed with a null error code.\");\n                    break;\n                case AsyncStatus.Canceled:\n                    error = new OperationCanceledException();\n                    break;\n                case AsyncStatus.Completed:\n                    if (_getResult != null)\n                    {\n                        result = _getResult(info);\n                    }\n\n                    break;\n                default:\n                    if (!initial)\n                    {\n                        throw new InvalidOperationException(\"The asynchronous operation completed unexpectedly.\");\n                    }\n\n                    _onCompleted(info, (iai, s) => Done(iai, s, false));\n                    return;\n            }\n\n            //\n            // Close as early as possible, before running continuations which could fail. In case of\n            // failure above, we don't close out the object in order to allow for debugging of the\n            // rogue implementation without losing state prematurely. Notice _getResult is merely\n            // an indirect call to the appropriate GetResults method, which is not supposed to throw.\n            // Instead, an Error status should be returned.\n            //\n            info.Close();\n\n            //\n            // Now we run the continuations, which could take a long time. Failure here is catastrophic\n            // and under control of the upstream subscriber.","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive.WindowsRuntime/AsyncInfoToObservableBridge.cs#L46-L82","documentation":"Done is first invoked with initial=true to hook completion callbacks. If it is called again (initial=false) and the status is neither Error, Canceled, nor Completed, the bridge has exhausted all known AsyncStatus values and considers the operation state invalid, throwing InvalidOperationException.","triggerScenarios":"Re-entry of Done with initial=false while the underlying IAsyncInfo reports an unrecognized/undefined AsyncStatus value.","commonSituations":"Rogue IAsyncInfo implementations returning out-of-range status values; corrupted or mocked async objects in tests.","solutions":["Ensure the IAsyncInfo implementation only returns valid AsyncStatus values (Started, Completed, Error, Canceled).","Check for custom/mock IAsyncInfo implementations that set undefined status values.","Catch InvalidOperationException around subscription and replace the source with a standard WinRT async operation."],"exampleFix":"// before (broken mock)\npublic AsyncStatus Status => (AsyncStatus)99;\n// after\npublic AsyncStatus Status => AsyncStatus.Completed;","handlingStrategy":"try-catch","validationCode":"if ((int)info.Status is < 0 or > 3) throw new InvalidOperationException(\"Invalid AsyncStatus value\");","typeGuard":"bool IsValidStatus(AsyncStatus s) => s is AsyncStatus.Started or AsyncStatus.Completed or AsyncStatus.Error or AsyncStatus.Canceled;","tryCatchPattern":"try { await obs; }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"completed unexpectedly\"))\n{ /* replace source with conformant async operation */ }","preventionTips":["Only consume IAsyncInfo objects from trusted producers","Avoid mocking AsyncStatus with out-of-range values in tests","Pin to conformant WinRT implementations"],"tags":["invalid-state","winrt","async","reactive-extensions"],"backgroundTag":"internal-invariant-violation","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}