Repository navigation
Create a new error for every aborted validation - #289
Merged
Merged
Conversation
Raising the shared ValidationAbortedError added the frames of every aborted validation to its traceback, which kept them alive for the life of the process.
A GraphQLError no longer adopts the traceback of the exception that is being handled when it is created, and the memoized errors of computations and the reasons of abort signals are raised again with their original tracebacks.
This was referenced Oct 25, 2026
Closed
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 #287.
Since 3.3.0a3,
validate()raised one module-levelValidationAbortedErrorwhenever the error limit was reached. Raising an existing exception again appends the new frames to its__traceback__, so every aborted validation lengthened the traceback of the shared error. That traceback kept the frames, and with them the document and validation context of every request, alive for the life of the process. Since any client can send a document with more than 100 validation errors, this could be used to exhaust the memory of a server. GraphQL.js also uses a shared error here, but JavaScript errors capture their stack only once, when they are created, so it is not affected.This change:
ValidationAbortedErrorevery time the error limit is reached, as GraphQL-core 3.2 did,OverlappingFieldsCanBeMergedRulereports an exceeded comparison budget,validation_aborted_error, which was not exported.With the reproduction from #287, the memory retained after 200 aborted validations drops from about 25 MB to a constant 180 KiB.
Tests check that every aborted validation gets its own error without traceback and context, that the documents and validation contexts are released with weak references (also when the validation is aborted while an exception is being handled, and through the comparison budget of
OverlappingFieldsCanBeMergedRule), and thatValidationAbortedErrorstill takes the arguments ofGraphQLError.A second commit fixes similar cases found in the rest of the code:
GraphQLErrorno longer adopts the traceback of the exception that is being handled when it is created. Python gives an error its traceback when it is raised, and reports the handled exception as its context. Errors that are created while handling an exception but never raised, like the error about an exceeded comparison budget, therefore no longer keep the frames of that exception alive.Thanks to @riodw for the detailed report and to @Fire162 for the first fix in #288.