"Run All Tests" hangs on *Running*

A fix for this issue has been implemented in version 2026.2.0
Implemented

"Run All Tests" hangs on *Running*

avatar

# Bug Report — "Run All Tests" hangs on *Running*; `ObjectDisposedException` in `CollectTestResultsAsync`

## Summary

Running tests from the admin console (**Automation > Tests > Run All Tests**, or a single test at

`/admin/settings/.../tests/{id}`) never completes. The UI shows the run stuck on **"Running"**

indefinitely. The Pester tests themselves execute and produce results (rows appear in `TestCases`

/`TestSuites`), but the server throws an `ObjectDisposedException` while finalizing the run, so the

`TestRuns` row is never marked complete (`Status` stays `Running`, `EndTime = -infinity`).

## Environment

| | |

|---|---|

| PowerShell Universal | **2026.1.7** (win-x64) |

| Host | Windows, `Universal.Server.exe` run on the host (developer license) — not containerized |

| Database backend | PostgreSQL 16 (Docker container), `Plugins: ["PostgreSQL"]` |

| Pester | 5.7.1 (bundled, resolved in the integrated runspace) |

| Repo mode | file-based repository at `.\Repository`; Git sync = PushOnly / Manual |

| Test files | 3 × `*.tests.ps1` at repo root, registered in `TestFiles` (Id/Path) |

## Steps to reproduce

1. Place one or more `*.tests.ps1` (Pester 5) files in the repository and register them under

Automation > Tests (rows in the `TestFiles` table).

2. Open the admin console → **Automation > Tests**.

3. Click **Run All Tests** (also reproduces with a single test run).

4. Observe the run shows **Running** and never transitions to Passed/Failed.

## Expected

The run completes; `TestRuns.Status` becomes a terminal state and per-test results show in the UI.

## Actual

- `TestRuns` row: `Status = Running (1)`, `EndTime = -infinity`, `Total = 0` — never finalized.

- `TestCases` / `TestSuites` rows **are** written (the tests ran), confirming execution succeeds and

only the *result collection / finalization* step fails.

- The server logs an unhandled `ObjectDisposedException`.

## Error / stack trace

```

[ERR][PowerShellUniversal.Testing.TestService] Error executing test run.

System.ObjectDisposedException: Cannot access a disposed object.

Object name: 'IServiceProvider'.

at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()

at PowerShellUniversal.DatabaseBase.GetTable[T]() in .../src/PowerShellUniversal/Services/DatabaseBase.cs:line 95

at PowerShellUniversal.Testing.TestService.CollectTestResultsAsync(TestRun testRun) in .../src/PowerShellUniversal.Testing/TestService.cs:line 119

at host.TestExecutionService.ExecuteTestAsync(TestRun testRun) in .../src/Host/TestExecutionService.cs:line 136

```

## Analysis

`CollectTestResultsAsync` runs after the Pester host process finishes and tries to persist results via

`DatabaseBase.GetTable[T]()`. By then the scoped `IServiceProvider` (and its `DbContext`) has already

been disposed, so the DB access throws. Because the exception is unhandled inside the test-execution

continuation, the `TestRuns` record is left in the `Running` state forever (the UI polls it and shows

the spinner indefinitely).

This looks like a **DI scope lifetime bug**: the result-collection continuation outlives the scope it

captured. It reproduces consistently on this build regardless of which/how many test files are run, and

is independent of the tests' content (they pass when run directly via `Invoke-Pester`).

## Impact

The built-in Test runner is effectively unusable — every run hangs and leaves an orphaned `Running`

record that must be cleared manually.

## Workarounds

1. **Run tests via a Script instead of the Test runner.** A `Invoke-Tests.ps1` script that calls

`Invoke-Pester` over the same `*.tests.ps1` files completes reliably (27/27 in ~5s) and reports a

pass/fail summary in the job output — it never touches `CollectTestResultsAsync`.

2. **Clear the stuck run** so the UI unsticks:

```sql

DELETE FROM "TestCases"; DELETE FROM "TestSuites"; DELETE FROM "TestRuns";

-- keep "TestFiles" (registration)

```

then restart the server.

## Suggested fix (for Devolutions)

Resolve/scope the `DbContext` (or capture an `IServiceScopeFactory` and create a fresh scope) inside

`CollectTestResultsAsync` rather than relying on the ambient scope captured when the run was started,

and wrap the finalization so any failure still writes a terminal `TestRuns.Status` (e.g. `Failed`)

instead of leaving it `Running`.

All Comments (1)

avatar

@alexrgreenwood We've got a fix coming for this in 2026.2.0. It was, in fact, a DI scope issue. Thanks for the report!

Adam Driscoll

PowerShell Expert and Software Architect at Devolutions

A fix for this issue has been implemented in version 2026.2.0