-
Notifications
You must be signed in to change notification settings - Fork 8
Remove-GitHubWorkflowRun does not delete all piped workflow runs #571
Description
Context
Remove-GitHubWorkflowRun accepts pipeline input from Get-GitHubWorkflowRun via ValueFromPipelineByPropertyName
on the Owner, Repository, and ID parameters. This enables a common bulk-deletion pattern:
Get-GitHubWorkflowRun -Owner PSModule -Repository GitHub |
Where-Object { $_.Status -ne 'in_progress' } |
Remove-GitHubWorkflowRunRequest
When piping workflow runs from Get-GitHubWorkflowRun through Where-Object into Remove-GitHubWorkflowRun,
only some runs are deleted — not all matching runs. Running the same Get-GitHubWorkflowRun pipeline
afterward still returns runs that should have been removed.
Reproduction steps
# Step 1: Delete all non-in-progress workflow runs
Get-GitHubWorkflowRun -Owner PSModule -Repository GitHub |
Where-Object { $_.Status -ne 'in_progress' } |
Remove-GitHubWorkflowRun
# Answer "A" (Yes to All) at confirmation prompt
# Step 2: Verify — expect no results
Get-GitHubWorkflowRun -Owner PSModule -Repository GitHub |
Where-Object { $_.Status -ne 'in_progress' }
# ACTUAL: Still returns workflow runs that should have been deletedObserved behavior
The confirmation prompt appeared for only one run (23967646592). After answering "Yes to All",
the command completed. Running the second command still returned 15 workflow runs — all from weeks earlier
(February 2026) — that should have been fed through the pipeline and deleted:
Terminal output
Confirm
Are you sure you want to perform this action?
Performing the operation "Delete workflow run" on target "PSModule/GitHub/23967646592".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): a
State Name ID Owner Repository CreatedAt UpdatedAt
----- ---- -- ----- ---------- --------- ---------
⛔ Process-PSModule 22281865302 PSModule GitHub 22.02.2026 17:29:19 22.02.2026 18:59:44
✅ PR #561 22281864810 PSModule GitHub 22.02.2026 17:29:16 22.02.2026 17:30:06
✅ Running Copilot coding agent 22281843433 PSModule GitHub 22.02.2026 17:27:51 22.02.2026 17:29:46
✅ PR #561 22281843002 PSModule GitHub 22.02.2026 17:27:49 22.02.2026 17:28:37
✅ Process-PSModule 22275476744 PSModule GitHub 22.02.2026 10:35:26 22.02.2026 15:29:38
✅ Push on main 22275476513 PSModule GitHub 22.02.2026 10:35:25 22.02.2026 10:36:08
❌ Process-PSModule 22267507645 PSModule GitHub 22.02.2026 00:47:32 22.02.2026 03:25:09
✅ Process-PSModule 22253968767 PSModule GitHub 21.02.2026 08:56:17 21.02.2026 12:37:16
❌ Process-PSModule 22246824677 PSModule GitHub 21.02.2026 00:43:47 21.02.2026 03:19:29
✅ Process-PSModule 22216586521 PSModule GitHub 20.02.2026 08:15:44 20.02.2026 22:01:32
✅ PR #555 22216585539 PSModule GitHub 20.02.2026 08:15:42 20.02.2026 08:16:33
✅ Addressing comment on PR #555 22216537392 PSModule GitHub 20.02.2026 08:14:00 20.02.2026 08:17:03
❌ Process-PSModule 22206472365 PSModule GitHub 20.02.2026 00:44:16 20.02.2026 03:15:28
❌ Process-PSModule 22199781665 PSModule GitHub 19.02.2026 20:56:49 19.02.2026 23:33:37
✅ PR #555 22199779468 PSModule GitHub 19.02.2026 20:56:46 19.02.2026 20:57:49
The deleted run (23967646592) does not appear in the subsequent listing, confirming that at least one deletion
succeeded. However, runs from February 2026 — weeks old and clearly not in_progress — were not deleted.
What is expected
All workflow runs that match the pipeline filter should be deleted. After the pipeline completes, re-running
the same Get-GitHubWorkflowRun query with the same filter should return no results (assuming no new runs
were created in the interim).
Acceptance criteria
- All workflow runs flowing through the pipeline are processed by
Remove-GitHubWorkflowRun - No silent failures — if a deletion fails, an error is surfaced
- Bulk deletion via pipeline works end-to-end without partial results
Technical decisions
Investigation is needed to determine the root cause. The following areas are the most likely candidates:
Possible cause 1 — Pagination in Get-GitHubWorkflowRun: The GitHub REST API
lists workflow runs
with paginated results. Invoke-GitHubAPI follows rel="next" link headers to fetch all pages.
However, the response wraps runs inside workflow_runs — each page yields
$_.Response.workflow_runs. If only the first page's runs are emitted before the pipeline
starts consuming, and a deletion error terminates the pipeline, subsequent pages would never be fetched.
A terminating error on any single DELETE call (e.g., 409 Conflict for a run in a protected state)
would kill the pipeline and prevent remaining items — including later pages — from being processed.
Possible cause 2 — Silent API errors during deletion: Remove-GitHubWorkflowRun calls
$null = Invoke-GitHubAPI @apiParams and discards the result. If the API returns a non-success
status code for certain runs (e.g., runs associated with a required status check, or runs still in a
transitional state), and Invoke-GitHubAPI throws a terminating error, the pipeline would be
interrupted and remaining items would not be processed. No error output would be visible if the
exception is swallowed or if the pipeline simply stops.
Possible cause 3 — $_ vs $Object in GitHubWorkflowRun constructor: The
constructor
mixes $_ (automatic variable from calling scope) with $Object (the constructor parameter).
Most properties use $_ instead of $Object:
GitHubWorkflowRun([PSCustomObject] $Object) {
$this.ID = $_.id # Uses $_
$this.NodeID = $_.node_id # Uses $_
$this.Name = $_.name # Uses $_
$this.Owner = [GitHubOwner]::new($Object.repository.owner) # Uses $Object
$this.Repository = [GitHubRepository]::new($Object.repository) # Uses $Object
# ... remaining properties all use $_ ...
}This works by coincidence when called from ForEach-Object { [GitHubWorkflowRun]::new($_) }
because $_ from the calling scope leaks into the class constructor in PowerShell. However, this
is fragile and could break across PowerShell versions or in contexts where $_ is not set.
Diagnostic approach: Add -Verbose and -Debug to the pipeline, count objects at each stage,
and check for thrown errors using -ErrorAction Stop or try/catch around the pipeline to
determine where items are lost.
Implementation plan
Diagnosis
- Reproduce the issue with
-Verboseand-ErrorVariableto capture any hidden errors - Count objects emitted by
Get-GitHubWorkflowRun, passed byWhere-Object, and received byRemove-GitHubWorkflowRunto identify where items are lost - Check if
Invoke-GitHubAPIthrows terminating errors on DELETE failures that would kill the pipeline
Fix — GitHubWorkflowRun constructor
- Replace all
$_references with$Objectin theGitHubWorkflowRunconstructor insrc/classes/public/Workflows/GitHubWorkflowRun.ps1
Fix — Error handling in Remove-GitHubWorkflowRun
- Wrap the
Invoke-GitHubAPIcall inRemove-GitHubWorkflowRunwith error handling that writes a non-terminating error instead of allowing a terminating error to kill the pipeline - Ensure the error message includes the run ID so the user knows which deletion failed
Tests
- Add test verifying pipeline input from
Get-GitHubWorkflowRunoutput processes all items - Add test verifying that a failed deletion does not terminate the pipeline for remaining items
Metadata
Metadata
Assignees
Labels
Type
Projects
Status