Skip to content

Error: The scope number '7' exceeds the number of active scopes. Parameter name: ScopeID #1856

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
DarkLite1 opened this issue Apr 9, 2019 · 18 comments

Comments

@DarkLite1
Copy link

DarkLite1 commented Apr 9, 2019

System Details

### VSCode version: 1.34.0-insider 56f1b4795fed05677eb82a21dac4fc1ab62d747b
x64

### VSCode extensions:
[email protected]
[email protected]
[email protected]


### PSES version: 2.0.0.0

### PowerShell version:

Name                           Value
----                           -----
PSVersion                      5.1.14409.1018
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14409.1018
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Issue Description

Sometimes I receive the following error:

[-] should be green 15.49s
ValidationMetadataException: The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
ParameterBindingValidationException: Cannot validate argument on parameter 'Message'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
at , S:\Test\Script.ps1: line 5

Script.ps1

$Error.Clear()

if ($Error) {
    $Error.ForEach( {
            Write-EventLog @EventErrorParams -Message $_.Exception.Message
        })
}

Script.Tests.ps1

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'

$Error.Clear()

Describe $sut {
    Mock Write-EventLog

    It 'should be green' {
        ."$here\$sut"
        $Error | Should -BeNullOrEmpty
    }
    In $TestDrive {
        Describe 'Test' {
            It 'should be green' {
                ."$here\$sut"
                $Error | Should -BeNullOrEmpty
            }
        }
    }
}

This does not always happen and it took me a long time to figure out that this only happens in VS Code and never in the PowerShell ISE. To narrow it further down the behavior can be consistently reproduced when setting a breakpoint at the line if ($Error).

When consulting the array of $Error at the breakpoint the following is shown:
image

I don;t know why this happens, but it could be related to #66. I'm using the PowerShell Preview 2.0.1.

@rjmholt
Copy link
Contributor

rjmholt commented Apr 9, 2019

Given that you're in the preview extension, it's likely this is a race condition somewhere between PSReadLine, the extension, and possibly the command being invoked. Fixing it is something we're hoping to achieve later this year when we try to tackle some architectural maintenance with the extension

@DarkLite1 DarkLite1 changed the title Error: The scope number '7' exceeds the number of active scopes. Error: The scope number '7' exceeds the number of active scopes. Parameter naem: ScopeID Apr 10, 2019
@DarkLite1 DarkLite1 changed the title Error: The scope number '7' exceeds the number of active scopes. Parameter naem: ScopeID Error: The scope number '7' exceeds the number of active scopes. Parameter name: ScopeID Apr 10, 2019
@yobyot
Copy link

yobyot commented Jul 15, 2019

Me, too.

I continue to be disheartened at the inability of vscode to replace the console, much less the ISE. On macOS, it's worse -- I end up having to run a VM just to use Windows PowerShell. Delaying such important debugger issues as this with "architectural maintenance" is a way of saying, to me ears, "We really didn't think through debugging hard enough. And we don't care that much about pwsh users -- talk to us about bugs in jscript and we're listening."

`### VSCode extensions:
[email protected]
[email protected]
[email protected]
[email protected]

PSES version: 1.12.1.0

PowerShell version:

Name Value


PSVersion 6.2.1
PSEdition Core
GitCommitId 6.2.1
OS Microsoft Windows 10.0.15063
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0`

@rjmholt
Copy link
Contributor

rjmholt commented Jul 15, 2019

I understand your frustration. The maintainers of the PowerShell extension are all PowerShell users and contributors. We tend to write a lot more PowerShell and C# than JS.

The difficulty in the debugger comes because of the mismatch between a generalised multithreaded language server experience, and PowerShell's single-threaded completion system.

The work we're currently undertaking to restructure the extension a bit will mean we can address and control the issues that creates much more readily. Rather than being a mutual exclusion, working on this at a lower level will end up being much better for the debugging experience as it stands.

To your point about using Windows PowerShell on macOS, Windows PowerShell is only supported on Windows. Could you describe the scenario you want to service there? Depending on what you're trying to do, it might be worth using remoting, trying out PowerShell 7, or having a look at the PSScriptAnalyzer compatibility rules.

@yobyot
Copy link

yobyot commented Jul 15, 2019

Thank you for your reply, @rjmholt.

I'm trying not to use Windows PowerShell anywhere. I'd prefer to be using PowerShell 6.2.1 everywhere but cannot because of my main gripe with vscode: it does not reliably replace the Windows PowerShell ISE for even simple debugging, not to mention its inability to advanced debugging like Sapien's PowerShell Studio.

My frustration is that as good as PowerShell is and as good as vscode is, together they actually stink -- at least in what I consider the basics: identical results to what's happening in a console, console editing and reliable debugging. Who's going to adopt PowerShell 6 or 7 on any platform if you get unrepeatable errors (happens to me all the time), different results from modules like Az and AWSPowerShell.NetCore in vscode from a debugger and just plain old hangs?

In short, PowerShell 6 and later is a language in search of a reliable coding environment -- which the vscode extension most certainly is not. I'm shocked and that a language that Microsoft brought to the world has fallen into such disrepair. Maybe it's function that nobody there "owns" the development environment. Or maybe it's just a product management miss. In any case, you guys have a real problem until something -- anything -- can reliably replace the creaky old ISE.

I realize I'm throwing rocks at a project that I'm not contributing to. But I'm a pwsh fan and recommend it highly to enterprises migrating to cloud so that the infrastructure staff can adopt a procedural language and when a declarative language like JSON is a bridge too far.

It's this opportunity I think the vscode extension is missing: catering to legions of admins (for whom pwsh was originally designed) who need to work in the cloud in a "comfortable" way. Asking them, non-devs who last week were racking servers and who are struggling to become full-stack cloud infrastructure engineers -- who must learn coding basics like git and debugging on the job, to use the combo of vscode and this extension in its current state is to doom them to failure.

@DarkLite1
Copy link
Author

DarkLite1 commented Jul 16, 2019

@yobyot I completely understand your point of view. I've had a similar feeling about using vscode to write PowerShell code in the past. That's why I opened 31555 to make PowerShell a fist class citizen of vscode.

Anyway, back to the issue at hand. The debugger should indeed not be polluted with inexplicable errors. @rjmholt can you tell us when improvements on this can be expected?

I'd also like to point out there are a lot of great people working on the PowerShell extension, PSReadline and the vscode internals like @rkeithhill @daviwil @TheIncorrigible1 @SeeminglyScience @TylerLeonhardt and many others. It's great to see the community working together to achieve something amazing. We're still not at the quality level of the PowerShell ISE but I can see that we're getting there slowly. Thanks guys for the great help already.

@SeeminglyScience
Copy link
Collaborator

I'm gonna quote a comment I wrote awhile ago about this:

That error is expected when debugging a script where a frame in the call stack is within a module. The number of scopes iterated when getting variables is based on the number of frames in the call stack. But because each SessionState has it's own stack of SessionStateScopes, so the amount of scopes does not equal the amount of frames in a call stack.

A possible fix would be to check the module of the command listed in the scope with frame.InvocationInfo.MyCommand.Module, but invoking Get-Variable in a different session state than the current EngineSessionState is tricky. If the session state belongs to a module we could do . $module { Get-Variable -Scope x }, but there's no publicly accessible way to get the top level session state. Even if we could get the top level session state, the only way to invoke a script within that session state is to create a fake module object and set it's session state.

$fakeModule = [psmoduleinfo]::new($false)
$fakeModule.SessionState = $topLevelSessionState
. $fakeModule { Get-Variable -Scope x }

But that's probably not intended behavior and is likely as dangerous as reflection.

All that said, this error is caught and wouldn't cause any crashes, we just don't get as much info for each frame as we'd like.

The issue is more complicated than it appears, and is mostly due to limitations in the engine. The fix I proposed (if it would even work) would be pretty time consuming to write. I typically only advise $Error to be used for interactive troubleshooting as it's very inconsistent. Modules can write to it, but not read it, event subscribers as well. Breakpoint actions can also pollute the error list.

You can get similar functionality from the -ErrorVariable common parameter. That will be the same type of list, but it will be limited to the errors generated within the command you use it on.

That's not to say that there is nothing to fix here, just that it's not particularly easy to fix with the PowerShell API's we have today.

@yobyot
Copy link

yobyot commented Jul 19, 2019

I'm apologize for attempting to beat a dead horse -- but the state of PowerShell debugging in vscode is a disaster. Check out this side-by-side demo. Bottom line: debugging a simple script yields different results in vscode on macOS vs. Windows. The two environments are running the same release of vscode, PowerShell Core and installed modules.

For example, consider the AWSPowerShell.NetCore cmdlet Set-Credential. In Windows PowerShell, PowerShell 6 on Windows and PowerShell 6 on macOS consoles, the cmdlet works perfectly. In Sapien PowerShell Studio using Windows PowerShell, the cmdlet succeeds. In Windows, debugging with vscode, the cmdlet succeeds.

But switch to macOS using vscode's debugger and it fails, as shown in the attached .gif of the same script being debugged in a Windows VM on macOS with PowerShell 6.2.2 side-by-side with the same script (literally, the same file on disk) in Windows, also running PowerShell 6.2.2.

IOW, the only environment in which the cmdlet fails is in the vscode debugger on macOS. That suggests to me it's not an issue with the AWS module and it's not an issue with the version of PowerShell. It's an issue with this debugger. The lack of reliability calls into question everything the debugger in vscode is telling you.

2019-07-19_12-40-12 (1)

@TylerLeonhardt
Copy link
Member

@yobyot can you share your debugging configuration? We’ve had similar reports with cmdlets that use SecureString under the hood. Also, this is probably not the best issue to have this conversation as your issue is different. Can you post it in here with your logs: #2050

@yobyot
Copy link

yobyot commented Jul 19, 2019

Done. Thanks for taking a look -- and for responding so quickly: #2050 (comment)

@DarkLite1
Copy link
Author

@SeeminglyScience I can understand the fact that the issue is hard or complicated to fix. But I'm quite sure that if the $Error variable in the PowerShell ISE stays clean of errors when there are non in the code, this should be true for that same code in vscode.

Errors about exceeding the number of active scopes... are just not acceptable when it's not coming from the script the developer wrote.`

@johndog
Copy link

johndog commented Aug 2, 2019

FWIW, I see these errors get added to $Global:Error every time I F10 in vscode debugger.

@SeeminglyScience wrote:

I typically only advise $Error to be used for interactive troubleshooting as it's very inconsistent. Modules can write to it, but not read it, event subscribers as well.

There are actually two ways I have used to enable modules to read $Error:

  1. $global:Error returns the same error collection as the module consumer
  2. Get-Variable -Scope 1 Error at module top-level will return the error collection accessible outside the module. It's brittle, so I'm not sure it ever makes sense to use this instead of global:.

I have no idea why $Error is created again at module scope, it's always empty, and it seems like the only reason $Error isn't otherwise readable from modules.

@SeeminglyScience continued:

Breakpoint actions can also pollute the error list.

You can get similar functionality from the -ErrorVariable common parameter. That will be the same type of list, but it will be limited to the errors generated within the command you use it on.

This is interesting, for two reasons:

  1. If there was a way to get -ErrorVariable functionality at current and child scopes (where it's too late to use -ErrorVariable because you're not at the call-site) I'd probably use it sometimes.

  2. @SeeminglyScience, @rjmholt: can the debugger use the equivalent of -ErrorVariable to stop adding things to $global:error? That would be a huge relief in its own right and might be enough to resolve this issue, even if the root-cause continues to manifest until the required architectural refactoring is complete.

@ghost ghost added the Needs: Maintainer Attention Maintainer attention needed! label Aug 2, 2019
@johndog
Copy link

johndog commented Aug 2, 2019

I might suggest that the debugger should always explicitly provide -ErrorVariable for every command it runs, so that its errors (designed or not) are always kept in a sandbox...

@SeeminglyScience
Copy link
Collaborator

FWIW, I see these errors get added to $Global:Error every time I F10 in vscode debugger.

@SeeminglyScience wrote:

I typically only advise $Error to be used for interactive troubleshooting as it's very inconsistent. Modules can write to it, but not read it, event subscribers as well.

There are actually two ways I have used to enable modules to read $Error:

  1. $global:Error returns the same error collection as the module consumer
  2. Get-Variable -Scope 1 Error at module top-level will return the error collection accessible outside the module. It's brittle, so I'm not sure it ever makes sense to use this instead of global:.

That's true, but you can't rely on those errors being your errors. They could be from previous invocations, other commands, or even event subscribers firing between script statements. That often leads to folks clearing them (which makes troubleshooting as a user difficult) or command failures based on incorrect information. $Error is great interactively, but there's always a better pattern otherwise.

I have no idea why $Error is created again at module scope, it's always empty, and it seems like the only reason $Error isn't otherwise readable from modules.

I'm guessing they intended for them to be entirely separate, but never got around to fully implementing that in an easy to understand way. That's just a guess though.

@SeeminglyScience continued:

Breakpoint actions can also pollute the error list.
You can get similar functionality from the -ErrorVariable common parameter. That will be the same type of list, but it will be limited to the errors generated within the command you use it on.

Yeah this is one of those better patterns. Using -ErrorVariable instead of $Error is a good alternative. It's not one I often turn to, but if you need to capture non-terminating errors, that's how I'd recommend doing it. Personally I prefer -ErrorAction Stop and a try/catch, but that may not always be feasible.

This is interesting, for two reasons:

  1. If there was a way to get -ErrorVariable functionality at current and child scopes (where it's too late to use -ErrorVariable because you're not at the call-site) I'd probably use it sometimes.

From the perspective of writing a script you can sort of. You could just wrap the rest of the script up in a function with CmdletBinding and attach -ErrorVariable to that. But yeah you can't really do that outside of design time.

  1. @SeeminglyScience, @rjmholt: can the debugger use the equivalent of -ErrorVariable to stop adding things to $global:error? That would be a huge relief in its own right and might be enough to resolve this issue, even if the root-cause continues to manifest until the required architectural refactoring is complete.

The problem with this one in particular is that it's from parameter validation, so even -ErrorAction Ignore does nothing unfortunately.

@SydneyhSmith SydneyhSmith removed the Needs: Maintainer Attention Maintainer attention needed! label Aug 8, 2019
@yobyot
Copy link

yobyot commented Mar 31, 2020

Is this ever going to improve? Every time I run into this, I spend an hour or more "remembering" that I cannot reliably debug a script in VS Code.

2020-03-31_09-15-34

@ghost ghost added the Needs: Maintainer Attention Maintainer attention needed! label Mar 31, 2020
@SydneyhSmith SydneyhSmith removed the Needs: Maintainer Attention Maintainer attention needed! label Mar 31, 2020
@efie45
Copy link

efie45 commented Mar 5, 2021

Not intending to just add 'me too' onto this issue but I've also been having trouble with this since I started with PowerShell over the last year or so. It makes searching for errors very difficult. Oftentimes 95% of the values in my $error variable are these types of errors. This is especially true when running tests in Pester as there are a lot of nested scopes.

@ghost ghost added the Needs: Maintainer Attention Maintainer attention needed! label Mar 5, 2021
@DarkLite1
Copy link
Author

Indeed @efie45 , when running Pestere tests this bug is really a nightmare when it comes to handling errors. I wish there was some more attention for this issue. It would be great if the $error array could just stay empty and not be polluted by code within vscode that fails.

@DarkLite1
Copy link
Author

A simple workaround I currently use when handling errors . Don't do this:

if ($error) {
    'We found an error but it is one coming from vscode error pollution
}

Instead do this:

if ($error.Exception.Message) {
    "These are the real errors coming from the script: $($error.Exception.Message -join ', ')"
}

@SydneyhSmith SydneyhSmith removed the Needs: Maintainer Attention Maintainer attention needed! label Mar 9, 2021
@ghost ghost added the Needs: Maintainer Attention Maintainer attention needed! label Aug 20, 2021
@andyleejordan andyleejordan removed the Needs: Maintainer Attention Maintainer attention needed! label Aug 20, 2021
@andyleejordan andyleejordan self-assigned this Nov 5, 2021
@andyleejordan andyleejordan added this to the Consider-vNext milestone Nov 5, 2021
@samjones3
Copy link

There is a StackOverflow thread (or more) asking about this sphere: https://stackoverflow.com/q/71562738/147637

@andyleejordan andyleejordan added Needs: Maintainer Attention Maintainer attention needed! and removed Needs: Maintainer Attention Maintainer attention needed! labels Mar 22, 2022
@SydneyhSmith SydneyhSmith removed this from the Consider-vNext milestone Aug 11, 2022
@SydneyhSmith SydneyhSmith moved this to Wishlist in Flying Fox Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Wishlist
Development

No branches or pull requests

10 participants