dotnet/reactive · error · InvalidOperationException

Did not get error output from program

Error message

Did not get error output from program

What it means

Companion check to the stdout timeout: after confirming stdout completed, RunScenarioAsync verifies the stderr task completed; if not it throws InvalidOperationException('Did not get error output from program'). The child process closed stdout but never finished writing/closing stderr, indicating a partial hang or abnormal termination.

Solutions

  1. Check whether the app leaves background processes/threads alive that hold stderr open
  2. Ensure the harness reads stdout and stderr concurrently to avoid pipe-buffer deadlock
  3. Inspect stderr content after the run for crash traces explaining the partial termination
  4. Increase the wait timeout or add explicit process kill + stream close on timeout
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the app terminates cleanly and closes both streams
p.WaitForExit(timeoutMs);
if (!p.HasExited) { p.Kill(entireProcessTree: true); throw new InvalidOperationException("App left stderr open; killed"); }

Try / catch

try
{
    await check.RunScenarioAsync(...);
}
catch (InvalidOperationException ex) when (ex.Message == "Did not get error output from program")
{
    // investigate lingering child processes / threads holding stderr
}

Prevention

When it happens

Trigger: stdOutTask completed but stdErrTask did not when the polling loop ended — the process finished standard output but stderr stayed open, e.g., a background thread still holding the error stream or the process hung after writing output.

Common situations: Child process spawns a lingering child/thread that keeps stderr open; process killed mid-write to stderr; pipe deadlock where stderr buffer filled while only stdout was being read.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at Rx.NET/Test/Gauntlet/Checks/TransitiveReferences/CheckTransitiveFrameworkReference/RunTransitiveFrameworkReferenceCheck.cs:287

                    if (!stdOutTask.IsCompleted)
                    {
                        // The process finished, but the standard output task is still running. It's possible that
                        // it is nearly done, so give it some time.
                        await Task.WhenAny(stdOutTask, Task.Delay(2000));
                    }
                    if (!stdErrTask.IsCompleted)
                    {
                        await Task.WhenAny(stdErrTask, Task.Delay(2000));
                    }

                    if (!stdOutTask.IsCompleted)
                    {
                        throw new InvalidOperationException("Did not get output from program");
                    }

                    if (!stdErrTask.IsCompleted)
                    {
                        throw new InvalidOperationException("Did not get error output from program");
                    }
                    runStdOut = await stdOutTask;
                    runStdErr = await stdErrTask;

                    await processTask;
                    runExitCode = process.ExitCode;
                }
#pragma warning restore IDE0063 // Use simple 'using' statement
            }
            else
            {
                //Debugger.Break();
                Console.WriteLine(r.BuildStdOut);
            }
            return new(r.BuildProcessExitCode, r.OutputFolder, r.BuildStdOut, runExitCode, runStdOut, runStdErr);
        }

        // TODO: we will actually build two apps: before and after upgrade.

View on GitHub (pinned to 94b5d5ab91)