Powershell: ConvertFrom-Json fails to parse project.lock.json

Created on 12 Aug 2016  路  17Comments  路  Source: PowerShell/PowerShell

$json = gc project.lock.json -Raw
ConvertFrom-Json $json

Expected: PowerShell should be able to parser the json data.
Actual: A useless error message which does not tell me what went wrong

ConvertFrom-Json : Cannot process argument because the value of argument "name" is not valid. Change the value of the
"name" argument and run the operation again.
At line:1 char:1
- ConvertFrom-Json $json
- ~~~~~~~~~~~~~~~~~~~~~~
  - CategoryInfo          : InvalidArgument: (:) [ConvertFrom-Json], PSArgumentException
  - FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
Area-Cmdlets Issue-Bug Resolution-Fixed

Most helpful comment

Bug is due to empty name for json dictionary entry, which appears to be valid by json standards, issue I believe is when converting to psobject:

Example from the project.lock.json:

"projectFileDependencyGroups": {
"": [
"System.Management.Automation >= 6.0.0-*"
],

thrown from line 4474 in MshMemberInfo.cs

                if (String.IsNullOrEmpty(name))
                {
                    throw PSTraceSource.NewArgumentException("name");
                }

"Cannot process argument because the value of argument "name" is not valid. Change the value of the "name" argument and run the operation again."

Reproducible with the following simple json:

{
"": "Test"
}

I am uncertain how to proceed further to fix this issue, hopefully this helps.

All 17 comments

Bug is due to empty name for json dictionary entry, which appears to be valid by json standards, issue I believe is when converting to psobject:

Example from the project.lock.json:

"projectFileDependencyGroups": {
"": [
"System.Management.Automation >= 6.0.0-*"
],

thrown from line 4474 in MshMemberInfo.cs

                if (String.IsNullOrEmpty(name))
                {
                    throw PSTraceSource.NewArgumentException("name");
                }

"Cannot process argument because the value of argument "name" is not valid. Change the value of the "name" argument and run the operation again."

Reproducible with the following simple json:

{
"": "Test"
}

I am uncertain how to proceed further to fix this issue, hopefully this helps.

@kittholland thanks for looking into this, best as I can tell per http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf, an empty string as the name is allowed and works in javascript. I guess the next step is to determine if the issue is in newtonsoft json parser.

From what I could see in the debugger, newtonsoft was OK with it, but converting the Jobject into a PSObject failed because the name was empty.

Ok, that makes sense (on why it failed). A HashTable will accept an empty string key, so it seems we should have PSObject support it as well. @kittholland are you going to work on a fix?

I have not looked deeply into what would be required, but I can give it a try.

We should also handle the Invoke-WebRequest/Invoke-RestMethod scenario where you're able to post a null JSON key as a string or as an object.

@SteveL-MSFT I think we still need to fix this one for 6.0.0. Valid JSON should be parsed by ConvertFrom-Json.

One other issue related to this is Invoke-Restmethod will silently fail and return null for valid json that is not PSCustomObject compatible.

This can be caused by NULL keys or case sensitive keys.

@kittholland are you still working on this or should I take it?

@SteveL-MSFT I think I'm out of my depth on a solution for this. Thanks to whoever takes it from here.

Forgot about the discussion in https://github.com/PowerShell/PowerShell/pull/2820. Introducing a json specific type isn't happening in 6.0.0 timeframe.

@SteveL-MSFT Can this issue be closed since PR #5043 provides a workaround via the -AsHashTable switch?

@bergmeister agree!

Any work arounds to this without upgrading PowerShell?

@DarwinJS You can either modify your json to be compatible with PSObjects, or you will need to modify/create a cmdlet to convert from json into hashtables.

@DarwinJS Since PowerShell Core is side by side and you can even get a self-contained version, you could just call into a newer version of pwsh from an old version of pwsh.

This is part of tooling that runs on thousands of machines I don't control and actually needs to be a single script with no public repo dependencies - so I resorted to the -replace method. Thanks.

Was this page helpful?
0 / 5 - 0 ratings