Repository navigation
Stop Import-Json injecting _SourceFile into returned objects #44
Description
Context and request
Observed behavior. Import-Json adds a _SourceFile note property to every PSCustomObject it returns:
if ($jsonObject -is [PSCustomObject]) {
Add-Member -InputObject $jsonObject -MemberType NoteProperty -Name '_SourceFile' -Value $resolvedPath.Path -Force
}The returned object therefore no longer matches the source document. Any import, modify, export round-trip writes _SourceFile into the output file, silently adding a key the user never wrote and which is meaningless to any other JSON consumer. examples/General.ps1 Example 18 performs exactly this sequence, and Example 9 prints the property as though it were a feature.
The property is undocumented: it appears nowhere in the command's comment-based help, only in a code comment reading Add file path information as a note property for reference.
Expected behavior. Import-Json returns the deserialized document and nothing else. Provenance, if the module offers it, is opt-in and does not contaminate the data.
Reproduction.
'{"name":"test"}' | Set-Content ./in.json
$data = Import-Json -Path ./in.json
$data | Get-Member -Name _SourceFile # present
Export-Json -InputObject $data -Path ./out.json -Force
Get-Content ./out.json # contains "_SourceFile"Environment. src/functions/public/Import-Json.ps1, lines 80-83. Module v1.2.3. Platform-independent.
Regression. Unknown. Present since the command was introduced as far as the current source shows.
Workaround. Strip the property after import with Select-Object -ExcludeProperty _SourceFile, or read the file with Get-Content -Raw | ConvertFrom-Json instead.
Acceptance criteria.
- Nothing
Import-Jsonreturns carries a property absent from the source document. - A file imported and immediately re-exported produces content structurally equivalent to the input.
- A regression test asserts the absence of
_SourceFileand fails against the current implementation. - The change is noted in the release notes, since anything depending on the property will break.
Technical decisions
Verified cause: the unconditional Add-Member call. There is no hypothesis to eliminate.
The property is removed rather than deprecated behind a switch. It is undocumented in the command's help, so there is no published contract to honour; and leaving it in place while adding an opt-out preserves the data-corruption default, which is the actual defect.
Provenance is a legitimate need — knowing which file an object came from is useful when importing a wildcard set. But it must not live inside the returned data. If it is reintroduced, the right shapes are a -PassThru-style wrapper object or a PSTypeName-decorated output with the path on a hidden member that ConvertTo-Json does not serialize. That design belongs in a follow-up, not in this correction.
examples/General.ps1 references the property in two places and must be updated in the same change, or it ships broken.
This is user-visible output content and warrants a Minor label, not Patch.
Implementation plan
- Add a regression test asserting an imported object has no
_SourceFilemember, and confirm it fails - Add a round-trip test asserting import then export reproduces the source structure exactly
- Remove the
Add-Membercall fromImport-Json - Update
examples/General.ps1Examples 9 and 18 to stop referencing the property - Confirm
Write-Verbose "Processing file: ..."still gives users the per-file visibility they need during wildcard imports - Update the comment-based help if it implies any added member
- Note the removal in the pull request body so it reaches the release notes
- Open a follow-up for opt-in provenance if there is appetite for it
- Apply the
Minorlabel
Activity