Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Memory leak: the shared `validation_aborted_error` keeps every traceback it is raised through

オープン 初心者向け
#287 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

@Fire162 がすでに取り組んでいます。

2026年10月24日 から。

  • #288 @Fire162 による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
api, backend

調査の方向性

共有の validation_aborted_error が発生する graphql/validation/validate.py から始め、validate() が max_errors に達したときにどう処理するかを確認してください。issue の再現手順では traceback とメモリの増加を確認できます。変更の前後に実行し、繰り返し呼び出しても traceback が増え続けた状態で保持されないことを確認してください。各検証呼び出しが独自のエラーを発生させ、メモリの増加が頭打ちになれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Since aab6d50 (first released in 3.3.0a3), validate() raises one shared, module-level ValidationAbortedError once max_errors is reached. When an existing exception object is raised again, Python adds the new frames to its existing __traceback__. So every aborted validation lengthens the singleton's traceback, and that traceback keeps those frames, and with them each request's document and validation context, alive for the life of the process.

Any client can trigger this by sending a query with more than 100 validation errors. In a long-running server, memory grows with every such request.

Reproduction (graphql-core 3.3.0, CPython 3.12):

import gc, tracemalloc
from graphql import build_schema, parse, validate
from graphql.validation.validate import validation_aborted_error

schema = build_schema("type Query { a: Int }")
document = parse("{ " + " ".join(f"f{i}" for i in range(101)) + " }")

tracemalloc.start()
validate(schema, document)
gc.collect()
base = tracemalloc.get_traced_memory()[0]
for _ in range(200):
    validate(schema, document)
gc.collect()
tb, n = validation_aborted_error.__traceback__, 0
while tb:
    n, tb = n + 1, tb.tb_next
print(n, (tracemalloc.get_traced_memory()[0] - base) // 1024, "KiB")

Result:

Repeated calls Traceback entries Memory retained
1 16 147 KiB
10 88 1,389 KiB
100 808 12,549 KiB
200 1,608 24,820 KiB

That is about 124 KiB more per aborted validation, with no upper limit. The same script on 3.2.13, which creates a new error each time, levels off at about 259 KiB.

Suggested fix: create a new ValidationAbortedError on each validate() call instead of reusing the module-level instance. Clearing __traceback__ before each raise would also work, but every caller's error list would still share one mutable error object.

主要言語
Python
スター
532
フォーク
154
平均マージ
1日 9時間
マージ済み PR(30日)
6

環境構築

  • Dockerfile・Docker Compose ファイルなし
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

graphql-python/graphql-core のほかの issue

graphql-python/graphql-core の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。