Skip to content

Fix Test-Json false positive errors when using oneOf or anyOf in schema#26618

Merged
iSazonov merged 2 commits into
PowerShell:masterfrom
yotsuda:fix-issue-21471-test-json-false-positives
Dec 17, 2025
Merged

Fix Test-Json false positive errors when using oneOf or anyOf in schema#26618
iSazonov merged 2 commits into
PowerShell:masterfrom
yotsuda:fix-issue-21471-test-json-false-positives

Conversation

@yotsuda
Copy link
Copy Markdown
Contributor

@yotsuda yotsuda commented Dec 16, 2025

PR Summary

Fixes false positive validation errors in Test-Json when using JSON schemas with oneOf or anyOf constructs by switching to hierarchical result processing and skipping valid nodes.

Fixes #21471

Based on #24577 by @sotteson1

PR Context

Problem

When validating JSON against schemas using oneOf or anyOf, Test-Json reports validation errors for all non-matching choices, even when one choice successfully matches. This produces many false positive errors that make the output unusable for complex schemas.

For example, with a oneOf schema defining smartphone (requires os) and laptop (requires arch) choices, a valid laptop entry would incorrectly report "Required properties [os] are not present" because the validation against the smartphone subschema also runs and its failure is reported as an error.

Solution

Changed the evaluation output format from List to Hierarchical and added a new ReportValidationErrors method that recursively walks the result tree, skipping nodes (and their children) where IsValid is true. This eliminates false positives from valid branches while still reporting actual validation errors.

PR Checklist

Changes Made

1. TestJsonCommand.cs (+29 lines, -10 lines)

  • Changed OutputFormat.List to OutputFormat.Hierarchical for schema evaluation
  • Replaced inline iteration with call to new ReportValidationErrors method
  • Added ReportValidationErrors method that recursively processes hierarchical results, skipping valid nodes and their children

2. Test-Json.Tests.ps1 (+195 lines)

  • Added oneOf schema with integer/string port pattern (simple case)
  • Added oneOf schema with smartphone/laptop device types (original issue scenario)
  • Added anyOf schema with smartphone/laptop device types
  • Added 6 test cases covering valid and invalid JSON for oneOf and anyOf schemas

Total: 2 files changed, 224 insertions(+), 10 deletions(-)

Behavior Examples

Before (false positives)

$schema = @'
{
    "type": "object",
    "properties": {
        "Devices": {
            "type": "array",
            "items": {
                "oneOf": [
                    { "properties": { "deviceType": { "const": "smartphone" }, "os": { "enum": ["iOS", "Android"] } }, "required": ["deviceType", "os"] },
                    { "properties": { "deviceType": { "const": "laptop" }, "arch": { "enum": ["x86", "x64", "arm64"] } }, "required": ["deviceType", "arch"] }
                ]
            }
        }
    }
}
'@

$json = @'
{
    "Devices": [
        { "deviceType": "laptop", "arch": "x64" },
        { "deviceType": "smartphone", "os": "iOS" },
        { "deviceType": "smartphone", "os": "WindowsPhone" }
    ]
}
'@

Test-Json -Json $json -Schema $schema -ErrorAction SilentlyContinue -ErrorVariable err
$err.Count  # Returns 10 (includes false positives for Devices/0 and Devices/1)

After (only relevant errors)

Test-Json -Json $json -Schema $schema -ErrorAction SilentlyContinue -ErrorVariable err
$err.Count  # Returns 4 (only errors for Devices/2)

Testing

All 55 tests pass (51 existing + 6 new).

New Test Cases

  • Test-Json does not report false positives for valid oneOf matches - Valid ports array returns true with no errors
  • Test-Json reports only relevant errors for invalid oneOf values - Invalid port reports error only for that item
  • Test-Json does not report false positives for valid oneOf device matches - Valid mixed device types returns true with no errors
  • Test-Json reports errors only for the invalid device in oneOf schema - Invalid device reports errors only for that device, not for valid ones
  • Test-Json does not report false positives for valid anyOf device matches - Valid mixed device types returns true with no errors
  • Test-Json reports errors only for the invalid device in anyOf schema - Invalid device reports errors only for that device, not for valid ones

Implementation Details

Design Decisions

  1. New method instead of modifying existing - ReportValidationErrors handles the recursive traversal with IsValid checks, keeping HandleValidationErrors unchanged for error reporting
  2. Hierarchical output - Provides tree structure needed to identify valid branches
  3. Early return on valid - Skips entire subtrees when IsValid is true, eliminating false positives efficiently
  4. HasDetails guard - Added HasDetails check before iterating child results for safety, which was not present in the original PR

Backward Compatibility

  • No API changes
  • Only affects error reporting, not validation results (true/false)
  • All 51 existing tests continue to pass

@iSazonov iSazonov added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Dec 16, 2025
@iSazonov iSazonov requested a review from Copilot December 16, 2025 17:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes false positive validation errors in Test-Json when using JSON schemas with oneOf or anyOf constructs. Previously, all non-matching choices would report errors even when validation succeeded. The fix switches to hierarchical result processing and skips reporting errors for valid nodes, eliminating false positives while preserving actual validation errors.

Key Changes:

  • Switched from List to Hierarchical output format for schema evaluation
  • Added recursive error reporting that skips valid nodes and their children
  • Added comprehensive test coverage for oneOf and anyOf scenarios

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
TestJsonCommand.cs Modified schema evaluation to use Hierarchical output format and added ReportValidationErrors method for recursive error processing with valid-node filtering
Test-Json.Tests.ps1 Added 6 new test cases with oneOf/anyOf schemas covering valid and invalid device/port scenarios to verify false positives are eliminated

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/powershell/Modules/Microsoft.PowerShell.Utility/Test-Json.Tests.ps1 Outdated
@iSazonov iSazonov self-assigned this Dec 17, 2025
@iSazonov iSazonov enabled auto-merge (squash) December 17, 2025 09:00
@iSazonov iSazonov merged commit d0d39c0 into PowerShell:master Dec 17, 2025
36 checks passed
@yotsuda yotsuda deleted the fix-issue-21471-test-json-false-positives branch December 17, 2025 09:43
kilasuit pushed a commit to kilasuit/PowerShell that referenced this pull request Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test-Json has false positives when using anyof and allof statements in JSON schema

3 participants