Uploaded image for project: 'Project Quay'
  1. Project Quay
  2. PROJQUAY-9757

Search function causing RecursionError

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Normal Normal
    • None
    • quay-v3.15.2
    • quay
    • False
    • Hide

      None

      Show
      None
    • False
    • User Experience
    • Customer Facing, Customer Reported

      This issue affects Quay, this bug happens only when a user who is a part of a very large number of organizations(e.g., 500-1000+) uses the conductSearch API.
      When this user searches, Quay tries to build a single, massive database query.
      This query chain becomes too long for the system to handle, causing it to crash with a RecursionError error and return an HTTP 500.

      STEPS FOR REPRODUCING THE PROBLEM:

      Create a large number of organizations(e.g 500-1000), you can use this script to automate this task:

      1. Save create_org.py file and execute it

       

      import requests
      QUAY_URL = "https://quay.example.com"
      AUTH_TOKEN = "Bearer <bearer> 
      NUM_ORGS_TO_CREATE = 1000
      HEADERS =
      {"Authorization": AUTH_TOKEN}
      print(f"Starting to create
      {NUM_ORGS_TO_CREATE}
      organizations...")
      for i in range(NUM_ORGS_TO_CREATE):
      org_name = f"bug_repro_org_
      {i:04d}
      "
      
      API call to create a new organization
      create_url = f" {QUAY_URL}
      /api/v1/organization/"
      payload =
      
      {"name": org_name}
      try:
      resp = requests.post(create_url, json=payload, headers=HEADERS)
      if resp.status_code == 201:
      print(f"Successfully created:
      {org_name}")
      else:
      print(f"Failed to create {org_name}
      (Status
      {resp.status_code}
      ):
      {resp.text}
      ")
      except requests.exceptions.RequestException as e:
      print(f"Error creating
      {org_name}
      :
      {e}
      ")
      print("Organization creation script finished.")
      

       

      2. Invoke the conductSearch API:

      $ curl -s -H "Authorization: Bearer <bearertoken>" -X GET "https://quay.example.com/api/v1/find/all?query=testdevops"

       

      3. Observe the 500 error in the pod logs:

      gunicorn-web stdout | File "/app/lib/python3.12/site-packages/peewee.py", line 606, in sql
      gunicorn-web stdout | return obj._sql_(self)
      gunicorn-web stdout | ^^^^^^^^^^^^^^^^^
      gunicorn-web stdout | File "/app/lib/python3.12/site-packages/peewee.py", line 1435, in _sql_
      gunicorn-web stdout | .sql(self.lhs)
      gunicorn-web stdout | ^^^^^^^^^^^^^
      gunicorn-web stdout | File "/app/lib/python3.12/site-packages/peewee.py", line 606, in sql
      gunicorn-web stdout | return obj._sql_(self)
      gunicorn-web stdout | ^^^^^^^^^^^^^^^^^
      gunicorn-web stdout | File "/app/lib/python3.12/site-packages/peewee.py", line 1427, in _sql_
      gunicorn-web stdout | with ctx(**overrides):
      gunicorn-web stdout | ^^^^^^^^^^^^^^^^
      gunicorn-web stdout | File "/app/lib/python3.12/site-packages/peewee.py", line 579, in _call_
      gunicorn-web stdout | self.state = self.state(**overrides)
      gunicorn-web stdout | ^^^^^^^^^^^^^^^^^^^^^^^
      gunicorn-web stdout | File "/app/lib/python3.12/site-packages/peewee.py", line 532, in _call_
      gunicorn-web stdout | return State(scope, parentheses, **settings)
      gunicorn-web stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      gunicorn-web stdout | RecursionError: maximum recursion depth exceeded
      gunicorn-web stdout | 2025-11-12 09:19:54,867 [253] [INFO] [gunicorn.access] - - [12/Nov/2025:09:19:54 +0000] "GET /api/v1/find/all?query=testdevops HTTP/1.0" 500 0 "" ""

              Unassigned Unassigned
              sunag@redhat.com Suparna Nag
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: