Repository navigation
Conversation
Contributor
Test ReportTest Results
Code Coverage (Java 25)
Changed Class Coverage (6 classes)
|
bbakerman
reviewed
Nov 2, 2026
| * Default maximum field count. | ||
| * Default maximum merged field count. | ||
| */ | ||
| public static final int DEFAULT_MAX_MERGED_FIELD_COUNT = 10_000; |
Member
There was a problem hiding this comment.
Is this too low - before we allowed 100_000 fields - so allowing for low "merging rates" - think this will catch out queries that were valid but had low "merge rates"
Is this too low as a default ??
This branch has not been deployed
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.
General
QueryComplexityLimitsnow reuse Good Faith's merged-field calculation. The general limit is now namedmaxMergedFieldCountand changes from 100,000 expanded field occurrences to 10,000 merged fields, with a separate 100,000 field-occurrence limit so repeated selections remain bounded even when they merge.Breaking changes and migration
The public API is renamed to make the counting change explicit. The old names are removed, with no compatibility aliases; callers must update their code and recompile.
QueryComplexityLimits.Builder.maxFieldsCount(int)maxMergedFieldCount(int)QueryComplexityLimits.getMaxFieldsCount()getMaxMergedFieldCount()QueryComplexityLimits.DEFAULT_MAX_FIELDS_COUNTDEFAULT_MAX_MERGED_FIELD_COUNTGoodFaithIntrospection.GOOD_FAITH_MAX_FIELDS_COUNTGOOD_FAITH_MAX_MERGED_FIELD_COUNTValidationErrorType.MaxQueryFieldsExceededMaxQueryMergedFieldCountExceededfor merged-field failures;MaxQueryFieldOccurrencesExceededfor occurrence failuresmaxMergedFieldCount(N)limits merged validation fields. To retain the old expanded-field budget ofmaxFieldsCount(N), usemaxFieldOccurrences(N); configure both when both budgets are needed. Duplicate selections can have fewer merged fields, while abstract-type grouping can produce more. The same number is not an equivalent policy for both metrics; examples are below.DEFAULT_MAX_MERGED_FIELD_COUNTis 10,000, replacing the old 100,000 expanded-field default. The separate default occurrence budget is 100,000. An operation with 10,001 distinct merged fields can now be rejected where it passed before. Good Faith's merged-field cap remains 500.Integer.MAX_VALUE. Setting onlymaxMergedFieldCount(N)does not enable an occurrence budget.Integer.MAX_VALUEdisables occurrence counting independently.MaxQueryMergedFieldCountExceeded, and occurrence failures useMaxQueryFieldOccurrencesExceeded. For Good Faith operations, occurrence failures are now validation errors instead ofBadFaithIntrospection; its merged-field/depth and coordinate failures still useBadFaithIntrospection. Merged-count messages explicitly say "merged fields". Earlier merged-field/depth checks can also change which failure is reported first. Update error-classification handling and exact-message assertions.@Internaltypes:GoodFaithIntrospectionCountsandFragmentComplexityInfoare removed; merged summaries useMergedFieldComplexityCounts.QueryComplexityLimitsExceedednow takes alongactual count and returnslongfromgetActual(), changing its constructor/method binary signatures.Limits and scope
Limits apply independently to every operation in the validated document, including unselected operations.
__schemaor__type, with Good Faith enabledGood Faith covers the whole mixed operation, including ordinary fields. Aliases, fragments and skipped root introspection selections also activate it;
__typenamealone does not. Its existing restriction remains: at most one merged occurrence per operation of each root__schema, root__type,__Type.fields,__Type.inputFields,__Type.interfacesand__Type.possibleTypes. Different aliases or parent positions count separately.QueryComplexityLimits.NONEdisables all three general limits; Good Faith remains independent. Disabling Good Faith leaves general limits active.What the two field counts mean
Both object and leaf fields count. Merged counting combines selections by response name and common parent type at the same response position, including their children. Occurrence counting charges every field at every fragment use, without merging. Spread and inline-fragment nodes themselves do not count.
maxMergedFieldCount)maxFieldOccurrences; previouslymaxFieldsCount){ node { name name } }{ node { ...F ...F } }, whereFselectsname{ a: node { name } b: node { name } }Depth is 2 in each example. All selections count regardless of
@skip/@include; validation does not coerce variables or remove mutually exclusive type branches.Merged counts can also exceed occurrence counts for abstract types. If
Query.nodereturns interfaceI, implemented byAandB, and theirchildfields returnI,AandBrespectively:{ node { child { a: name b: name c: name } ... on A { child { name } } ... on B { child { name } } } }With
name: Stringon all three types, this has 9 field occurrences and 11 merged validation fields: onenode, plus five fields in each concrete-parent child group. These are the validator's groups, not ENO runtime-type expansion counts.The committed 886-character fragment-doubling fixture has only two AST field nodes and two merged fields, but 33,554,433 field occurrences. The occurrence limit rejects it by default with
MaxQueryFieldOccurrencesExceeded.Implementation and protection boundaries
Merged counts bound response structure, not list lengths or resolver cost; the separate
QueryComplexityCalculatorAPI remains available. Occurrence counting follows initial merge validation, so it is not a preflight bound on all validation work. Parser limits, fragment-cycle detection and error limits remain necessary; this PR does not fix the existing stack overflow for very long acyclic fragment chains.Verification and performance