dotnet/reactive · error · InvalidOperationException

The asynchronous operation failed with a null error code.

Error message

The asynchronous operation failed with a null error code.

What it means

Rx.NET's AsyncInfoToObservableBridge adapts WinRT IAsyncInfo objects to observables. When the underlying IAsyncInfo reports AsyncStatus.Error, the bridge propagates its ErrorCode as the failure; this InvalidOperationException is thrown when ErrorCode is null, i.e. the async operation claims to have failed but carries no error object, which indicates a rogue/buggy IAsyncInfo implementation.

Solutions

  1. Fix or replace the non-conformant IAsyncInfo implementation so it sets a valid ErrorCode when completing with AsyncStatus.Error
  2. Wrap subscription/ToTask calls in try-catch and handle InvalidOperationException as 'operation failed with unspecified error'
  3. Log the operation ID/status and report the bug to the component vendor

Example fix

// before: custom async op that fails without error code
info.ErrorCode == null // -> InvalidOperationException
// after: implement IAsyncInfo correctly
public HResult ErrorCode => _exception != null ? _exception.HResult : new HResult(0);
Defensive patterns

Strategy: try-catch

Validate before calling

if (asyncInfo.Status == AsyncStatus.Error && asyncInfo.ErrorCode == null) throw new InvalidOperationException("Rogue IAsyncInfo: failed without ErrorCode");

Type guard

static bool HasValidErrorCode(IAsyncInfo info) => info.Status != AsyncStatus.Error || info.ErrorCode != null;

Try / catch

try { observable.Subscribe(...); } catch (InvalidOperationException ex) when (ex.Message.Contains("null error code")) { /* treat as unspecified failure */ }

Prevention

When it happens

Trigger: Calling ToObservable (or subscribing) on a custom/broken Windows Runtime IAsyncInfo implementation whose Status becomes AsyncStatus.Error while ErrorCode returns null.

Common situations: Interoperating with hand-rolled or third-party WinRT async components (often projected via C++/CX or custom winmd types) that violate the IAsyncInfo contract by failing without setting an error code.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/7f4031c1441107fb. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Foundation/AsyncInfoToObservableBridge.cs:49

                progress?.Report(p);
            });

            Done(info, info.Status, true);
        }

        private void Done(IAsyncInfo info, AsyncStatus status, bool initial)
        {
            var error = default(Exception);
            var result = default(TResult);

            //
            // Initial interactions with the IAsyncInfo object. Those could fail, which indicates
            // a rogue implementation. Failure is just propagated out.
            //
            switch (status)
            {
                case AsyncStatus.Error:
                    error = info.ErrorCode ?? throw new InvalidOperationException("The asynchronous operation failed with a null error code.");
                    break;
                case AsyncStatus.Canceled:
                    error = new OperationCanceledException();
                    break;
                case AsyncStatus.Completed:
                    if (_getResult != null)
                    {
                        result = _getResult(info);
                    }

                    break;
                default:
                    if (!initial)
                    {
                        throw new InvalidOperationException("The asynchronous operation completed unexpectedly.");
                    }

                    _onCompleted(info, (iai, s) => Done(iai, s, false));

View on GitHub (pinned to 94b5d5ab91)