Skip to content

Mutating PSTaskJob.ChildJobs from ForEach-Object -Parallel -AsJob throws unhandled exception and crashes PowerShell #26160

@kborowinski

Description

@kborowinski

Prerequisites

Steps to reproduce

The PowerShell session crash occurs if you remove one of the child jobs from a ForEach-Object -Parallel job:

  1. Start a new PowerShell 7.5.x or 7.6.0 session
  2. Run:
# Create a parallel job with multiple child jobs that each sleep for a bit
$j = 0..20 | ForEach-Object -Parallel {
    $r = Get-Random -Minimum 5 -Maximum 15
    Start-Sleep $r
    $r
} -AsJob

# Obtain the ChildJobs collection
$x = [Collections.Generic.List[Management.Automation.Job]]$j.ChildJobs
# And remove one entry while the jobs are still starting
$x.RemoveAt(15)

Note: Using the random 5–15 second delay keeps the job in “starting” long enough to hit the exception.

Affected PowerShell versions: 7.5.3, latest build of 7.6.0 from main (didn't test on 7.4.x)
Tested on: Windows 11 25H2 x64.

Stack trace

An error has occurred that was not properly handled. Additional information is shown below. The PowerShell process will exit.
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at System.Management.Automation.PSTasks.PSTaskJob.<Start>b__16_0(Object _) in D:\DEVELOPMENT\PowerShellCore\src\System.Management.Automation\engine\hostifaces\PSTask.cs:line 1140
   at System.Threading.QueueUserWorkItemCallback.Execute()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

The stack trace indicates the crash occurs inside PSTaskJob.Start on a ThreadPool callback while enumerating an internal List<T>. Mutating the ChildJobs list at the same time invalidates that enumerator, producing InvalidOperationException which is not caught and bubbles up, terminating the process.

Expected behavior

PowerShell should not terminate.
Either:
- Removing the child job succeeds safely, or
- The operation is rejected with a normal (catchable) error, or
- ChildJobs is exposed as read-only to user code.

Actual behavior

An error has occurred that was not properly handled. Additional information is shown below. The PowerShell process will exit.
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at System.Management.Automation.PSTasks.PSTaskJob.<Start>b__16_0(Object _) in D:\DEVELOPMENT\PowerShellCore\src\System.Management.Automation\engine\hostifaces\PSTask.cs:line 1140
   at System.Threading.QueueUserWorkItemCallback.Execute()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

Error details

N/A – the session terminates due to an unhandled exception before Get-Error can be run.

Environment data

Name                           Value
----                           -----
PSVersion                      7.6.0-preview-4
PSEdition                      Core
GitCommitId                    7.6.0-preview-4-168-gd5267d2ee661695e2dab15fdb651b4e23cd0503f
OS                             Microsoft Windows 10.0.26200
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0, 5.0, 5.1, 6.0, 7.0}
PSRemotingProtocolVersion      2.4
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageThe issue is new and needs to be triaged by a work group.WG-Enginecore PowerShell engine, interpreter, and runtimeWG-NeedsReviewNeeds a review by the labeled Working Group

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions