Context and request
Observed behavior. Export-Json -Depth is only honoured when -Compact is also supplied. Without -Compact, the parameter has no effect at all.
The compact path serializes with the caller's depth:
$formattedJson = $objectToExport | ConvertTo-Json -Depth $Depth -Compress
The pretty path delegates to Format-Json, which does not accept a depth and hard-codes its own:
$formattedJson = Format-Json -InputObject $objectToExport -IndentationType $IndentationType -IndentationSize $IndentationSize
# Format-Json internally: $inputObject | ConvertTo-Json -Depth 100 -Compress:$Compact
Compounding this, -Depth defaults to 2 while Format-Json uses 100. So the same object exported the same way produces different data depending on a formatting switch.
Reproduced against main:
$deep = [pscustomobject]@{ l1 = [pscustomobject]@{ l2 = [pscustomobject]@{ l3 = [pscustomobject]@{ l4 = 'deep' } } } }
$deep | ConvertTo-Json -Depth 2 -Compress
# {"l1":{"l2":{"l3":"@{l4=deep}"}}} <- what Export-Json -Compact writes by default
The nested object at level 4 is flattened into the string "@{l4=deep}". The written file is no longer a faithful representation of the input, and the loss is silent.
Expected behavior. -Depth applies identically on both paths, and its default does not silently truncate ordinary nested data.
Reproduction.
$deep = [pscustomobject]@{ l1 = [pscustomobject]@{ l2 = [pscustomobject]@{ l3 = [pscustomobject]@{ l4 = 'deep' } } } }
Export-Json -InputObject $deep -Path ./compact.json -Compact -Force
Export-Json -InputObject $deep -Path ./pretty.json -Force
Get-Content ./compact.json # truncated at level 3
Get-Content ./pretty.json # fully preserved
Environment. src/functions/public/Export-Json.ps1 ($Depth default 2, lines 74 and 138) and src/functions/public/Format-Json.ps1 (hard-coded -Depth 100, line 59). Module v1.2.3. Reproduced on PowerShell 7 on Windows; the logic is platform-independent.
Regression. Unknown. Present since Export-Json was introduced as far as the current source shows; no prior working version identified.
Workaround. Always pass an explicit -Depth high enough for the data and avoid -Compact, or serialize with ConvertTo-Json directly and use the -JsonString parameter set.
Acceptance criteria.
Export-Json -Depth <n> produces identical nesting depth with and without -Compact.
- The default depth does not truncate ordinary nested objects.
- A regression test exports the same object on both paths and asserts the results are structurally equivalent.
- No warning-free silent truncation remains on either path.
Technical decisions
Verified cause: two independent serialization sites with different depths, and only one of them reachable by the caller's -Depth.
The fix is to give Format-Json a -Depth parameter and have Export-Json pass its value through, so there is one depth applied at one place. Hard-coding 100 in both would remove the inconsistency but also remove the caller's control, which the parameter exists to provide.
The default changes from 2 to something that does not truncate realistic data. Format-Json's existing 100 is the natural choice and is already the effective default on the pretty path — so aligning on it changes behaviour only for -Compact callers who were being truncated, which is the defect being fixed.
Adding -Depth to Format-Json is an additive parameter change and not breaking. Raising Export-Json's default is user-visible in output content and warrants a Minor label.
Not in scope: ConvertTo-Json emits a warning when it truncates; whether the module should surface that is a separate design question.
Implementation plan
Context and request
Observed behavior.
Export-Json -Depthis only honoured when-Compactis also supplied. Without-Compact, the parameter has no effect at all.The compact path serializes with the caller's depth:
The pretty path delegates to
Format-Json, which does not accept a depth and hard-codes its own:Compounding this,
-Depthdefaults to2whileFormat-Jsonuses100. So the same object exported the same way produces different data depending on a formatting switch.Reproduced against
main:The nested object at level 4 is flattened into the string
"@{l4=deep}". The written file is no longer a faithful representation of the input, and the loss is silent.Expected behavior.
-Depthapplies identically on both paths, and its default does not silently truncate ordinary nested data.Reproduction.
Environment.
src/functions/public/Export-Json.ps1($Depthdefault2, lines 74 and 138) andsrc/functions/public/Format-Json.ps1(hard-coded-Depth 100, line 59). Module v1.2.3. Reproduced on PowerShell 7 on Windows; the logic is platform-independent.Regression. Unknown. Present since
Export-Jsonwas introduced as far as the current source shows; no prior working version identified.Workaround. Always pass an explicit
-Depthhigh enough for the data and avoid-Compact, or serialize withConvertTo-Jsondirectly and use the-JsonStringparameter set.Acceptance criteria.
Export-Json -Depth <n>produces identical nesting depth with and without-Compact.Technical decisions
Verified cause: two independent serialization sites with different depths, and only one of them reachable by the caller's
-Depth.The fix is to give
Format-Jsona-Depthparameter and haveExport-Jsonpass its value through, so there is one depth applied at one place. Hard-coding100in both would remove the inconsistency but also remove the caller's control, which the parameter exists to provide.The default changes from
2to something that does not truncate realistic data.Format-Json's existing100is the natural choice and is already the effective default on the pretty path — so aligning on it changes behaviour only for-Compactcallers who were being truncated, which is the defect being fixed.Adding
-DepthtoFormat-Jsonis an additive parameter change and not breaking. RaisingExport-Json's default is user-visible in output content and warrants aMinorlabel.Not in scope:
ConvertTo-Jsonemits a warning when it truncates; whether the module should surface that is a separate design question.Implementation plan
-Compactand asserting structural equivalence, and confirm it fails-Depthparameter toFormat-Jsonand use it in place of the hard-coded100-DepthfromExport-Jsonthrough toFormat-Jsonon the pretty pathExport-Json's-Depthdefault so ordinary nested data is not truncated-Depthtruncates identically on both pathsMinorlabel