Skip to content

Add a maximum depth of 128 levels - #83

Merged
tgharold merged 3 commits into
masterfrom
tgh-20261002-max-validation-depth-128
Oct 2, 2026
Merged

tgharold merged 3 commits into
masterfrom
tgh-20261002-max-validation-depth-128

Conversation

@tgharold

@tgharold tgharold commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Motivation

The validator calls itself once for each level of the object graph, and .NET cannot catch a StackOverflowException. A chain of about 1,500 objects, or a property that builds a new object on each read (Vector Zero => new Vector()) on a type without an Equals override, ends the process. This was the open "maximum depth" item for the 3.0 series. The limit is 128, which is twice the default depth of System.Text.Json and Newtonsoft. A JSON document within the limit of 64 stays within about 63 levels here.

Past the limit the validation fails. It does not throw and it does not stop silently, because a graph that nobody validated must not pass.

Summary

  • The depth of an object is the number of segments in its path. Each property step and each collection index is one level, and the root is level 0.
  • An object at level 128 is validated. An object at level 129 is not validated, and the validation fails with one error at its path: "The object is nested more than 128 levels deep and was not validated." The walk does not go deeper below that object.
  • Leaf values, objects seen before and objects stopped by the Equals ancestor rule never trigger the error, so a valid chain of exactly 128 objects still passes.
  • The limit is an internal constant. It is not a setting.
  • A tree that holds its children in a List uses two levels for each tree level, so it can be 64 levels deep.
  • README and CHANGELOG describe the limit. The changelog entry is marked BREAKING, because a graph deeper than 128 levels passed before and fails now.
  • Two existing tests used graphs deeper than the limit. They now stay below it: the chain in GraphSizeTests and UpgradeCompatibilityTests, and the tree in GraphSizeTests.

Test plan

  • New MaxDepthTests (17 specs) cover chains, trees, collections of collections, the async method, a null results list, a computed property and a 600-object chain on a 1 MB stack.
  • The first commit holds the specs and fails until the second commit adds the limit. The Vector spec is in the second commit, because it would crash the test host without the limit.
  • Full suite on net8.0 and net10.0: 520 passed, 14 skipped, 0 failed.
  • The net481 test project builds with -p:IncludeNetFramework=true.
  • Windows CI runs the net481 tests.

tgharold and others added 3 commits October 2, 2026 07:57
Specs for objects in chains, in collections and in collections of
collections. An object at level 128 is validated. An object at level
129 is not validated and fails the validation with an error at its
path. These specs fail until the limit is added.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The walk calls itself once for each level, so a graph of about 1,500
objects, or a property that builds a new object on each read, overflowed
the stack. An object at a path of more than 128 segments is now not
validated, and the validation fails with one error at its path.

Tests that used a deeper graph now stay below the limit.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@tgharold
tgharold merged commit 4c8460d into master Oct 2, 2026
3 checks passed
@tgharold
tgharold deleted the tgh-20261002-max-validation-depth-128 branch October 2, 2026 12:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant