Skip to content

"Cannot overwrite variable ... because the variable has been optimized" related to foreach and explicitly typed variable #25607

@ravindUwU

Description

@ravindUwU

Prerequisites

Steps to reproduce

Observed a weird bug, and I'm not quite sure how to accurately describe it, so please feel free to reword the issue title as appropriate 😅.

I'm noticing that when I run this snippet 👇, PowerShell throws an error that reads "Cannot overwrite variable e because the variable has been optimized. Try using the New-Variable or Set-Variable cmdlet (without any aliases), or dot-source the command that you are using to set the variable".

& {
	[string[]] $arr = 'a', 'b'

	$arr | ForEach-Object {
		[string] $e = $_
		"ForEach-Object $e"
	}

	foreach ($e in $arr) {
		"foreach $e"
	}
}

I've also noticed that the error doesn't show up when,

  • $e within the ForEach-Object is not explicitly typed as a [string]; i.e., simply $e = $_ instead of [string] $e = $_.
  • The script block is removed, and its contents moved to the top level?
  • The foreach moved above the ForEach-Object.

Related: the conversation around this message on the PowerShell Discord.

Expected behavior

PS> . './snippet.ps1'
ForEach-Object a
ForEach-Object b
foreach a
foreach b

Actual behavior

PS> . './snippet.ps1'
WriteError:./snippet.ps1:5:3
Line |
   5 |          [string] $e = $_
     |          ~~~~~~~~~~~~~~~~
     | Cannot overwrite variable e because the variable has been optimized. Try using the New-Variable or Set-Variable cmdlet
     | (without any aliases), or dot-source the command that you are using to set the variable.
ForEach-Object 
WriteError:./snippet.ps1:5:3
Line |
   5 |          [string] $e = $_
     |          ~~~~~~~~~~~~~~~~
     | Cannot overwrite variable e because the variable has been optimized. Try using the New-Variable or Set-Variable cmdlet
     | (without any aliases), or dot-source the command that you are using to set the variable.
ForEach-Object 
foreach a
foreach b

Error details

Expand
Exception             : 
    Type        : System.Management.Automation.SessionStateUnauthorizedAccessException
    ErrorRecord : 
        Exception             : 
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Cannot overwrite variable e because the variable has been optimized. Try using the New-Variable or Set-Variable 
cmdlet (without any aliases), or dot-source the command that you are using to set the variable.
            HResult : -2146233087
        TargetObject          : e
        CategoryInfo          : WriteError: (e:String) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : VariableNotWritableRare
        InvocationInfo        : 
            ScriptLineNumber : 5
            OffsetInLine     : 3
            HistoryId        : 12
            ScriptName       : C:\path\to\snippet.ps1
            Line             : [string] $e = $_

            Statement        : [string] $e = $_
            PositionMessage  : At C:\path\to\snippet.ps1:5 char:3
                               +         [string] $e = $_
                               +         ~~~~~~~~~~~~~~~~
            PSScriptRoot     : C:\path\to
            PSCommandPath    : C:\path\to\snippet.ps1
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, C:\path\to\snippet.ps1: line 5
                                at <ScriptBlock>, C:\path\to\snippet.ps1: line 4
                                at <ScriptBlock>, C:\path\to\snippet.ps1: line 1
                                at <ScriptBlock>, <No file>: line 1
    ItemName    : e
    TargetSite  : 
        Name          : SetVariable
        DeclaringType : [System.Management.Automation.SessionStateScope]
        MemberType    : Method
        Module        : System.Management.Automation.dll
    Message     : Cannot overwrite variable e because the variable has been optimized. Try using the New-Variable or Set-Variable cmdlet 
(without any aliases), or dot-source the command that you are using to set the variable.
    Data        : System.Collections.ListDictionaryInternal
    Source      : System.Management.Automation
    HResult     : -2146233087
    StackTrace  : 
   at System.Management.Automation.SessionStateScope.SetVariable(String name, Object value, Boolean asValue, Boolean force, 
SessionStateInternal sessionState, CommandOrigin origin, Boolean fastPath)
   at System.Management.Automation.SessionStateInternal.SetVariable(VariablePath variablePath, Object newValue, Boolean asValue, Boolean 
force, CommandOrigin origin)
   at System.Management.Automation.SessionStateInternal.SetVariable(VariablePath variablePath, Object newValue, Boolean asValue,
CommandOrigin origin)
   at System.Management.Automation.VariableOps.SetVariableValue(VariablePath variablePath, Object value, ExecutionContext
executionContext, AttributeBaseAst[] attributeAsts)
   at System.Management.Automation.Interpreter.FuncCallInstruction`5.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject          : e
CategoryInfo          : WriteError: (e:String) [], SessionStateUnauthorizedAccessException
FullyQualifiedErrorId : VariableNotWritableRare
InvocationInfo        : 
    ScriptLineNumber : 5
    OffsetInLine     : 3
    HistoryId        : 12
    ScriptName       : C:\path\to\snippet.ps1
    Line             : [string] $e = $_

    Statement        : [string] $e = $_
    PositionMessage  : At C:\path\to\snippet.ps1:5 char:3
                       +         [string] $e = $_
                       +         ~~~~~~~~~~~~~~~~
    PSScriptRoot     : C:\path\to
    PSCommandPath    : C:\path\to\snippet.ps1
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, C:\path\to\snippet.ps1: line 5
                        at <ScriptBlock>, C:\path\to\snippet.ps1: line 4
                        at <ScriptBlock>, C:\path\to\snippet.ps1: line 1
                        at <ScriptBlock>, <No file>: line 1

Environment data

Name                           Value
----                           -----
PSVersion                      7.5.1
PSEdition                      Core
GitCommitId                    7.5.1
OS                             Microsoft Windows 10.0.26100
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-BugIssue has been identified as a bug in the productResolution-No ActivityIssue has had no activity for 6 months or moreUp-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributorsWG-Enginecore PowerShell engine, interpreter, and runtimeWG-ReviewedA Working Group has reviewed this and made a recommendation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions