Skip to content

Error starting PowerShell 7.4.0+ #20706

Closed

Description

Prerequisites

Steps to reproduce

  1. Install PowerShell 7.4.0
  2. Start it
  3. Create a powershell.config.json and set PSModulePath to multiple paths, separated by ; (path separator char) (see reference).
  4. See it fail

Expected behavior

It starts, like 7.3 did.

Actual behavior

It fails with:

PowerShell 7.4.0
The shell cannot be started. A failure occurred during initialization:
Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'startIndex')

Error details

Not possible.

Environment data

Not possible, but it is version 7.4.0.

Visuals

This is starting from Nushell:

from nu

This is starting it from Windows Terminal:

from wt

Additional context

Downloaded and installed this file: https://github.com/PowerShell/PowerShell/releases/download/v7.4.0/PowerShell-7.4.0-win-x64.msi

I debugged and found out that the exception is ocurring at this location (ModuleIntrinsics.UpdatePath):

insertIndex = path.IndexOf(Path.PathSeparator, PathContainsSubstring(path, pathToAdd));

The arguments for UpdatePath are:
path: a string with a ; separated list of paths
pathToAdd: another string with a ; separated list of paths
insertIndex: 0

The call that is failing is the one to path.IndexOf, which is passed ; and -1 (which is the result from the call to PathContainsSubstring).

The problem only happens because pathToAdd has several paths with the ; separator. If it was a single path without ; it would work.

The issue seems to have been introduced in commit 3710671.

Activity

  1. giggio commented on Nov 16, 2023

    @giggio
    Author

    rhubarb-geek-nz I did, I hadn't.

  2. B-Art commented on Nov 18, 2023

    @B-Art

    There are at least 4 ways to install Pwsh on Windows:
    From MSStore, via MSI, via Winget and Unzipping the download.
    Which one did you use Giovanni Bassi (@giggio) ?
    https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4

  3. giggio commented on Nov 18, 2023

    @giggio
    Author

    First I tried via winget. Then via the MSI download. Same result.

  4. giggio commented on Nov 22, 2023

    @giggio
    Author

    Have you tried completely uninstalling the previous MSI first? Not ideal I know, in-place updates should work. Use "Add or Remove programs" to see what is installed, and also check the directory "c:\Program Files\PowerShell\7"

    I have.

    I have now also tried installing the Microsoft Store Version, and I get the same error:
    image

  5. giggio commented on Nov 22, 2023

    @giggio
    Author

    Tried now using the global tool, it also does not work:

    image

    I installed 7.3.10, as it still works. :(

  6. giggio commented on Jan 25, 2024

    @giggio
    Author

    The problem persists at version 7.4.1, released more recently.

    image

  7. giggio commented on Jan 25, 2024

    @giggio
    Author

    Also, tried using version 7.5 preview from the store, also broken.

    image

  8. giggio commented on Mar 13, 2024

    @giggio
    Author

    I have tracked the error and added the explanation of why it is happening to the additional context section of the issue.

  9. changed the title [-]Error starting PowerShell 7.4.0[/-] [+]Error starting PowerShell 7.4.0+[/+] on Mar 13, 2024
  10. added a commit that references this issue on Mar 13, 2024
    90e2da2
  11. Alvaka-KThor commented on Apr 4, 2024

    @Alvaka-KThor

    I am also experiencing this issue. I've had to use PSModulePath environment variable within System Properties in the meantime, which is not a perfect workaround.

  12. w-boyd commented on May 27, 2024

    @w-boyd

    On Linux:

    ForEach-Object: /home/vsts/work/_temp/f3a905a8-4984-469a-b3ba-7a9ba49e76af.ps1:5
    Line |
       5 |  "whatever" | ForEach-Object -Parallel { $_ }
         |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         | An unexpected error has occurred while processing ForEach-Object
         | -Parallel input. This may mean that some of the piped input did not get
         | processed. Error: System.ArgumentOutOfRangeException: Index was out of
         | range. Must be non-negative and less than or equal to the size of the
         | collection. (Parameter 'startIndex')    at System.String.IndexOf(Char
         | value, Int32 startIndex, Int32 count)    at
         | System.Management.Automation.ModuleIntrinsics.UpdatePath(String path,
         | String pathToAdd, Int32& insertIndex)    at
         | System.Management.Automation.ModuleIntrinsics.GetModulePath(String
         | currentProcessModulePath, String hklmMachineModulePath, String
         | hkcuUserModulePath)    at
         | System.Management.Automation.ModuleIntrinsics.SetModulePath()    at
         | System.Management.Automation.ModuleIntrinsics..ctor(ExecutionContext
         | context)    at
         | System.Management.Automation.ExecutionContext.InitializeCommon(AutomationEngine engine, PSHost hostInterface)    at System.Management.Automation.AutomationEngine..ctor(PSHost hostInterface, InitialSessionState iss)    at System.Management.Automation.Runspaces.LocalRunspace.DoOpenHelper()    at System.Management.Automation.Runspaces.RunspaceBase.CoreOpen(Boolean syncCall)    at System.Management.Automation.PSTasks.PSTaskPool.GetRunspace(Int32 taskId)    at System.Management.Automation.PSTasks.PSTaskPool.Add(PSTaskBase task)    at Microsoft.PowerShell.Commands.ForEachObjectCommand.<InitParallelParameterSet>b__67_2(Object _).
    

    On Windows:

    "C:\Program Files\PowerShell\7\pwsh.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". 'D:\a\_temp\86498521-8914-4ea7-ba0c-67b8bb7a6633.ps1'"
    The shell cannot be started. A failure occurred during initialization:
    Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'startIndex')
    ##[error]PowerShell exited with code '70'.
    

    Azure DevOps pipeline yaml to reproduce the issue:

    jobs:
    - job: windows
      pool:
          vmImage: windows-latest
      steps:
      - pwsh: |
          $filePath = Join-Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY "powershellmodules"
          $separator = $isWindows ? ";" : ":"   
          $updatedPSModulePath = $env:PSModulePath, $filePath -join $separator
          $powershellConfigPath = Join-Path $PSHOME 'powershell.config.json'
          if (-not (Test-Path $powershellConfigPath)){
            New-Item -Path $powershellConfigPath -ItemType File -Force
            $config = @{
              PSModulePath = $updatedPSModulePath
            }
          }
          else {
            Write-Verbose "Found existing powershell config, updating PSModulePath"
            $config = Get-Content -Path $powershellConfigPath | ConvertFrom-Json -AsHashtable -Depth 100
            $config["PSModulePath"] = $updatedPSModulePath
          }
          Write-Verbose "Pushing content to $powershellConfigPath" -Verbose
          $config | ConvertTo-Json -Depth 100 | Tee-Object -FilePath $powershellConfigPath
        displayName: Update PSModulePath
    
      - pwsh: |
          Write-Verbose ('$env:PSModulePath {0}' -f $env:PSModulePath) -Verbose
          "whatever" | ForEach-Object -Parallel { $_ }
        displayName: Debug
    
    - job: linux
      pool:
          vmImage: ubuntu-latest
      steps:
      - pwsh: |
          $filePath = Join-Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY "powershellmodules"
          $separator = $isWindows ? ";" : ":"   
          $updatedPSModulePath = $env:PSModulePath, $filePath -join $separator
          $powershellConfigPath = Join-Path $PSHOME 'powershell.config.json'
          if (-not (Test-Path $powershellConfigPath)){
            New-Item -Path $powershellConfigPath -ItemType File -Force
            $config = @{
              PSModulePath = $updatedPSModulePath
            }
          }
          else {
            Write-Verbose "Found existing powershell config, updating PSModulePath"
            $config = Get-Content -Path $powershellConfigPath | ConvertFrom-Json -AsHashtable -Depth 100
            $config["PSModulePath"] = $updatedPSModulePath
          }
          Write-Verbose "Pushing content to $powershellConfigPath" -Verbose
          $config | ConvertTo-Json -Depth 100 | Tee-Object -FilePath $powershellConfigPath
        displayName: Update PSModulePath
    
      - pwsh: |
          Write-Verbose ('$env:PSModulePath {0}' -f $env:PSModulePath) -Verbose
          "whatever" | ForEach-Object -Parallel { $_ }
        displayName: Debug
    
  13. 2 remaining items

  14. hoffmanntravis commented on Nov 6, 2024

    @hoffmanntravis

    I have reproduced this issue on Powershell 7.4.6 locally. This works:

    {
        "PSModulePath": ":"
    }
    

    This does not:

    {
        "PSModulePath": ";"
    }
    

    File Path:
    C:\Users<user>\Documents\PowerShell\powershell.config.json

    This seems like a clear case of regression. Please investigate and fix.

  15. hoffmanntravis commented on Nov 6, 2024

    @hoffmanntravis

    Couple more notes. This is still broken in Powershell Preview 7.5:

    PowerShell 7.5.0-preview.5
    The shell cannot be started. A failure occurred during initialization:
    Index was out of range. Must be non-negative and less than or equal to the size of the collection. (Parameter 'startIndex')
    
    [process exited with code 70 (0x00000046)]
    You can now close this terminal with Ctrl+D, or press Enter to restart.
    

    Also, note that in the example I listed in my last comment, the semicolon delimiter by itself alone is enough to break the startup of powershell.

    According to this document, ; should be the delimiting character:
    https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_psmodulepath?view=powershell-7.4#modifying-psmodulepath

    Editing the config file is described here:
    https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_config?view=powershell-7.4#psmodulepath

    The PSModulePath environment variable contains a list of folder locations that are searched to find modules and resources.
    Configuration files for PowerShell, replacing Registry configuration.
  16. jborean93 commented on Nov 12, 2024

    @jborean93
    Collaborator

    Opened #24568 to fix this problem.

  17. hoffmanntravis commented on Nov 13, 2024

    @hoffmanntravis

    Jordan Borean (@jborean93) First, I just wanted to say thanks for putting a PR together and getting this some attention after a long time idle.

    TLDR: The underlying thesis of my comments below are we are an impacted customer of fairly advanced users that are feeling a lot of pain from this, so maybe that tips the scales towards merging. I read through the PR and noticed your comment below.

    _"Waiting on an answer from the WG also takes way too much time and if I'm being honest I doubt this one will actually get merged anytime soon which is a pity.

    Maybe I'll just bite the bullet and do it because I really dislike the current behavior and how it works."_

    In response to that, I want to put out that we are a medium size azure customer that is fairly heavily impacted by this. We use Azure DevOps with Azure. We built our YAML deploy pipelines and our internal libraries around the notion of PSModulePath being overridable and extensible by deployment agents and users. When we use AzurePowershell@5, it actually overrides any previously set environment variables (at least with respect to PSModulePath) unless we set one on the task in YAML directly. I also tried setting it via the registry (no permission on managed agents), via a #vso var, via user env var, and via system env vars. No luck. This is burdensome compared to how it worked previously.

    Prior to the issue, we ran one task template with no parameters per job that writes the modules to disk, we update the machine environment variable, and we are done. Developers can consume our libraries and templates with little to no knowledge of our tools.

    Without this fix, it becomes very difficult to manage those modules and how we have it set up. Yes, we can likely do an install-module or something, but checking out a repository, writing to disk, and setting the environment variable works great for us. And then it broke so we've been stuck on 7.2 for months. Recently I ended up writing my own randomizer and testing with NIST tools instead of using PS 7.4 Get-SecureRandom, which would have been so much more convenient.

    Not sure if that tips the scales or not in favor of merging but I hope it does 🙂. And maybe provides a little cover if there are issues. You can definitely blame me, because we're really feeling pain with out it, so there's one reason to do it anyway haha. We really dislike the behavior right now ourselves, because it doesn't work for us at all and broke our existing process.

    Thanks so much for your help!
    Travis

  18. ChrisTX commented on Oct 28, 2026

    @ChrisTX

    This is fixed on master by #26565 (in 7.7.0-preview.1 and later), which also fixed the duplicate #26536. Could this issue be closed, and could a fix be considered for 7.6, since that's the current LTS release? v7.6.9 still crashes at startup, or in ForEach-Object -Parallel runspaces, when $env:PSModulePath is already set (e.g. when starting pwsh from pwsh) and a powershell.config.json sets PSModulePath to multiple paths.

    #26565 is a fairly large refactor, which needed test fixes afterwards (#27343, #27344), so it may not suit a servicing release. A smaller fix that only touches the two places that break is:

    • UpdatePath: PathContainsSubstring(path, pathToAdd) returns -1 for a combined pathToAdd, so path.IndexOf(Path.PathSeparator, -1) throws. Look up the last entry of pathToAdd instead.
    • AddToPath: advance insertPosition after each inserted entry, so a combined path keeps its order, and compare it against result.Length instead of basePath.Length.

    We've shipped this in the Arch Linux (AUR) package of 7.6.9, and the full Pester and xUnit suites pass with it. I'm happy to open a PR against the 7.6 release branch if you'd take it there.

  19. kilasuit commented on Nov 3, 2026

    @kilasuit
    Collaborator

    Christian Pfeiffer (@ChrisTX) it's probs best if you don't mind raising a new issue asking for the backport of #26565 & other required test fixes that were needed or you can make your suggestion about a possible smaller fix instead & the team can decide which option they decide on taking to the 7.6.x release branch.

    Whilst in the meantime we can close this issue out as it now having been fixed. Sound good to you?

  20. ChrisTX commented on Nov 3, 2026

    @ChrisTX

    Ryan Yates (@kilasuit) Can do if that's better. For reference, I'm using this minimal patch in my build for ArchLinux AUR. If you think that's better, I can open a PR for that? It's really just this fix, and would thus work in a minimal fashion on the 7.6 branch?

  21. kilasuit commented on Nov 3, 2026

    @kilasuit
    Collaborator

    The final decision on whether it make senses to diverge with a new fix or it makes it easier just to backport what's already been merged, is a maintainer team decision to make.

    Which is easier & quicker decided with a short issue that's to the point.

  22. ChrisTX commented on Nov 3, 2026

    @ChrisTX

    Ryan Yates (@kilasuit) Opened #28306 for the 7.6 fix, with both options. Fine to close this one.

  23. added and removed
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    In-PRIndicates that a PR is out for the issue
    on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions