-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Invoke-Expression validates nonexistent parameter default values. #8778
Comments
@mklement0 If you add a valid initializer then it's fine PSCore (2:59) > Invoke-Expression 'param([ValidateSet("one", "two")] $foo = "one") "hi"'
hi Note that the behaviour is the same with the $ExecutionContext.InvokeCommand.InvokeScript('param([ValidateSet("one", "two")] $foo) "hi"') as well as {param([ValidateSet("one", "two")] $foo) "hi}.Invoke() Why the error isn't raised when running a script does warrant further investigation. |
@BrucePay that discrepancy is weird. This pattern of declaring a parameter with a validation attribute and then not giving it a default value is pretty common and has been the way it is understood to work for a long time. I think the better question is why is this error appearing in this context when this pattern has been used for a long time now in declaring parameters. 😕 |
The scenarios that fail use The scenarios that don't fail are from a compiled command AST, which creates a command processor instead. More specifically, here's the line from the Note Same thing happens with the |
Thanks, @vexx32 and @SeeminglyScience. @vexx32 is correct that not specifying a value has always worked and should work in all situations. PS> . { param([ValidateSet("one", "two")] $foo = "invalid") $foo }
invalid Also, the fact that I haven't delved into the code, but, functionally, it seems that the default value / lack thereof is validated when it shouldn't be. |
Thinking about this some more, based on @BrucePay's response and @SeeminglyScience's findings:
I see two possible resolutions:
|
@mklement0 I believe it's just a bug. I think the |
@SeeminglyScience: That's definitely the most straightforward way to resolve this issue. However, the question is whether we see value in preventing invalid default values, which currently doesn't happen (and the bug fix wouldn't give us). I personally see value in that (e.g., during refactoring of a validation set you may forget to update the default value accordingly), but there are two considerations:
|
@mklement0 while I do agree that preventing invalid default values is probably a good idea — after all, one can generally check |
Also interestingly it seems that if you declare a parameter with validation, then change the value of that variable inside the script to something that is not a valid value; it will throw this exception. e.g. Save this as a file and execute, supplying one of the three valid options for this parameter [ biff, bash, bosh ]; [Cmdletbinding()]
Param(
[Parameter(Mandatory=$True)]
[ValidateSet("biff","bash","bosh")]
[String]$Word
)
$ErrorActionPreference = "Stop";
Write-Host "Let's give this thing something to do";
$Word = "boosh"; # This will throw an exception aaand..
It's quite interesting to learn that the params are continually evaluated to see whether they confirm to the validation attributes. -J |
@johngeorgef1, this is actually standard behavior, and not specific to & { param([ValidateRange(1,2)] $foo) $foo = 3 }
MetadataError: The variable cannot be validated because the value 3 is not a valid value for the foo variable. It is not well known, but you can apply constraints to any variable, not just a parameter variable: [ValidateRange(1,2)] $foo = 1; # regular variable with validation attribute
$foo = 3 # same error as above While that is a powerful feature, constraints that apply to parameter variables only are inappropriately applied in at least one case: #10426 |
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
2 similar comments
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes. |
Note: The repro below uses the
ValidateSet
attribute to demonstrate the problem, but at least one other attribute is affected too, namelyValidatePattern
- possibly more. Presumably, fixing the problem for one attribute also fixes it for the others.Update:
The core issue is that when script block text with parameter declarations is invoked via
Invoke-Expression
, default-parameter-value validation for parameters that haveValidate*
attributes takes place in an overzealous manner: even if there is no default value, the implied value of$null
is evaluated against the validation attributes - however, it should be possible to simply omit a default value for validation-constrained parameters (and that is how it works with direct invocations of functions / scripts / script-block literals).As an aside: The helpful aspect of this validation - namely if there is a default value - is currently missing from direct function / script / script-block literal invocations; remedying that is the subject of For validation-constrained function parameters, prevent invalid default values. #8795.
Steps to reproduce
Expected behavior
Actual behavior
The text was updated successfully, but these errors were encountered: