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
- Check whether the app leaves background processes/threads alive that hold stderr open
- Ensure the harness reads stdout and stderr concurrently to avoid pipe-buffer deadlock
- Inspect stderr content after the run for crash traces explaining the partial termination
- 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
- Kill the entire process tree on timeout so no child keeps streams open
- Avoid background threads writing to Console in the test app
- Always read stdout and stderr in parallel
- Treat unterminated streams as a hang signal and dump diagnostics
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
- Did not get output from program
- Did not get output from program
- Did not get output from program
- ArgumentNullException
- The operation has timed out.
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)