Repository navigation
Report every failing element of a root list, array or dictionary [patch] - #87
Merged
Merged
Conversation
A collection at the payload root was never claimed, so System.Text.Json's own collection converter validated each element on its own. Only the first failing element was reported, and without its index or key. HasRules now claims a list, array or dictionary whose elements reach a decorated member, and GraphValidator.Validate starts from Descend so the root collection is walked with [i] and key paths. Sets, stacks and bare IEnumerable stay unclaimed, because the walk cannot pair them positionally. Fixes #50 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017vfJW23J6RZjbfVi3bACn8
|
This was referenced Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #50
What changed
RequirementRuleCompiler.HasRulesnow claims a list, array or dictionary (anything assignable toIListorIDictionary) whose element or value type reaches a decorated member. Nested lists and dictionaries count too, soDictionary<string, List<T>>andList<List<T>>are claimed. A collection that holds itself ends the search.IEnumerablestay unclaimed, for the positional-pairing reasons given onGraphValidator.DescendList. If one were claimed, its elements would be materialized factory-free and then never walked. Unclaimed, each element is still validated on its own, as before.GraphValidator.Validatestarts fromDescendrather thanWalk, so a root array or object-shaped dictionary is walked with[i]and key paths.Claiming a collection only matters at the payload root. Below a claimed holder, the subtree is already materialized through factory-free options, so holders behave as before.
Deserialize<List<SimpleConfig>>on[A, B, A][Tuning][0].Tuning,[2].TuningDeserialize<SimpleConfig[]>[Tuning][0].Tuning,[2].TuningDeserialize<Dictionary<string,SimpleConfig>>[Tuning]a.Tuning,b.TuningSide effect on System.Text.Json's own errors at a root collection
{"Mode":"oops"}in element 1) now get exactly the path and line System.Text.Json reports without the factory,$[1].Mode. Before this change the path was$[1], with the inner path kept in the inner exception. The threeErrorLocationTeststhat pinned the old shape now assert the paths match exactly.$on the same line, rather than at$[0]. A claimed root buffers its whole value through the caller's reader, and the depth limit fails during that buffering. A claimed root object already behaves this way.$[0].x. It doesn't help: System.Text.Json's own read-ahead (TrySkip) hits the limit first.HashSet<T>, which still goes through a per-element converter, and a new test pins the$root behaviour.Tests
RootCollectionTestscovers:List<T>,T[],Dictionary<string,T>andList<List<T>>, each reporting every violation in one exception;IEnumerable<T>,List<HashSet<T>>, collections of undecorated types and a self-listing type are not.EligibilityTests.BareCollectionsAreStillNotClaimed, nowBareCollectionsOfNotEmptyTypesAreClaimed, andRequirementRuleCompilerTests.HasRulesRejectsPrimitivesStringsAndEnums, which now usesList<int>.README "How it works" and CLAUDE.md "Reachability" now describe root collections.
Generated by Claude Code