Repository navigation
Inconsistent and unclear error messaging #10056
Description
When a user provides an invalid value to a parameter, the error message that they receive should be crystal clear. Today, that is not the case. For example, consider these empty command definitions:
function Test-Mandatory {
param(
[Parameter(Mandatory, ParameterSetName='StringTest')]
[string]
$String,
[Parameter(Mandatory, ParameterSetName='ObjectTest')]
[object]
$Object
)
}
function Test-Validator {
param(
[ValidateNotNullOrEmpty()]
[string]
$String,
[ValidateNotNull()]
[object]
$Object
)
}When a parameter is marked as Mandatory, if it's a string, it cannot be empty. If it's a non-value type object, it cannot be null. That's built in behavior. Command authors can also add ValidatNotNullOrEmpty or ValidateNotNull validators that ensure that a parameter is not null or empty, or not null, respectively. These are more or less the same thing: logic to ensure that non-null or non-empty values are provided to parameters; however, the error messages returned to users are not consistent and not necessarily as clear as they should be. Below are some command invocations along with the errors that are produced in PowerShell Core 6.2.1 today. Note that these are just the error message -- the command name, position and other details have been stripped.
| Command | Error Message |
|---|---|
Test-Mandatory -String $null |
Cannot bind argument to parameter 'String' because it is an empty string. |
Test-Mandatory -Object $null |
Cannot bind argument to parameter 'Object' because it is null. |
Test-Validator -String $null |
Cannot validate argument on parameter 'String'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. |
Test-Validator -Object $null |
Cannot validate argument on parameter 'Object'. The argument is null. Provide a valid value for the argument, and then try running the command again. |
The message that each of these errors tries to convey to the caller is that they provided an invalid value into a parameter, and sometimes they suggest what should be done while encouraging them to try again. Unfortunately, the error message that appears does not actually convey that message very well.
Cannot bind argument to parameter...
While it is true that the parameter binder was unable to bind the value provided to a certain parameter, the end user doesn't need to know those technical details.
Cannot validate argument on parameter...
These error messages are misleading, and could sound like PowerShell was unable to perform the validation on a parameter value.
...because it is an empty string.
This does not properly cover the case where $null is accidentally passed into a mandatory string parameter, which is not helpful to end users.
Also, the Mandatory error messages do not suggest the user try again, but the Validator error messages do.
In all cases, these error messages should be clear, consistent, and since PowerShell is used interactively in a shell, directed towards the end user so that they can more easily correct the problem.
I propose that we change the error messages for the commands shown above to the messages shown below instead.
| Command | Error Message |
|---|---|
Test-Mandatory -String $null |
The null or empty value provided for the 'String' parameter is invalid. Try running the command again with a value for the 'String' parameter that is not null or empty. |
Test-Mandatory -Object $null |
The null value provided for the 'Object' parameter is invalid. Try running the command again with a value for the 'Object' parameter that is not null. |
Test-Validator -String $null |
The null or empty value provided for the 'String' parameter is invalid. Try running the command again with a value for the 'String' parameter that is not null or empty. |
Test-Validator -Object $null |
The null value provided for the 'Object' parameter is invalid. Try running the command again with a value for the 'Object' parameter that is not null. |
These messages are targeted towards the end user who is invoking the command, consistent regardless of whether the parameter is Mandatory or using a ValidateNotNull or ValidateNotNullOrEmpty validator, they clearly identify the problem, and they tell the user what to do to fix the problem.
Better, yes?
Environment data
Name Value
---- -----
PSVersion 6.2.1
PSEdition Core
GitCommitId 6.2.1
OS Microsoft Windows 10.0.17763
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Activity
iSazonov commentedon Jul 4, 2019
It would still be nice to have differences in the messages for the mandatory parameters (to identity source)
KirkMunro commentedon Jul 4, 2019
I disagree, because I think that information just adds potential confusion for the end user, and these messages are really meant for the end user.
If someone invokes a command and does not meet the command requirements according to parameter binding or validation, they need to know what was wrong. I don't think they need to know if a parameter they used was mandatory, because they used it, so who cares.
If they did not use a mandatory parameter, then they need to be told that parameter such-and-such is required, but in that case they are prompted for input, so again, who cares, because for the end user it doesn't really need to be part of the error message.
Behind the scenes the category info or the fully qualified error id can indicate the actual source of the issue so that a command author can identify where the error comes from.
microsoft-github-policy-service commentedon Nov 16, 2023
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.
microsoft-github-policy-service commentedon Nov 23, 2023
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.