Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

ConvertFrom-Json unpacks arrays with 1 item and behaves oddly with empty object

I am trying to figure out how to stop ConvertFrom-Json from unpacking array types if they have one or zero items.

I have read these related posts:
ConvertTo-JSON an array with a single item
How to prevent ConvertFrom-Json from collapsing nested arrays if there's 1 element

After reading these, I don’t think I am experiencing the member access enumeration because I am not using the access operator.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I attempted to use ConvertFrom-Json without the use of pipelining but that didn’t fix the issue as it did for someone using ConvertTo-Json

Here is a simple example with output:

$x = '[{"a": 1, "b": 2}]'
$y = ConvertFrom-Json -InputObject $x

$a = '[]'
$b = ConvertFrom-Json -InputObject $a

Write-Host $y -ForegroundColor Green
Write-Host $y.GetType() -ForegroundColor Green

Write-Host $b -ForegroundColor Green
Write-Host $b.GetType() -ForegroundColor Green
@{a=1; b=2} # first object in array, not array
System.Management.Automation.PSCustomObject # treats as object instead of array
# nothing was printed here because b is null
InvalidOperation: C:\Users\username\Test.ps1:11:1 # error from trying to print the type of b
Line |
  11 |  Write-Host $b.GetType() -ForegroundColor Green
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | You cannot call a method on a null-valued expression.

The kind of output I expected was the GetType() calls to return System.Object[]

Additional Context:

I am using the github cli to get lists of PRs for different repos and aggregate some data for some internal workflows. Obviously it is possible for a repo to have 0, 1 or more PRs and I am hoping to avoid any special logic for the 0 or 1 case, as an empty array or array with one item can follow the same code path as an array with many items.

>Solution :

The behavior you’re seeing implies that you’re using PowerShell (Core) 7+ rather than Windows PowerShell.

While your command happens to work in Windows PowerShell, it relies on behavior that contravenes the usual pipeline behavior, i.e. enumerating arrays – see the (now closed) GitHub issue #3424 for background information.

It is for this reason that in PowerShell 7+ ConvertFrom-Json now enumerates the elements of a parsed-from-JSON array by default, and requires opt-in in order to request that a such an array be output as a single object, using the -NoEnumerate switch:

$x = '[{"a": 1, "b": 2}]'

# Note the -NoEnumerate switch (v7+)
$y = ConvertFrom-Json -NoEnumerate -InputObject $x

$y.GetType().Name # -> 'Object[]', proving that the array was preserved.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading