When we claim an org that was already claimed by the same user, Quay sometimes errors out with a duplicate entry exception which causes a 500:
2025-04-18T20:03:23.350983294Z gunicorn-web stdout | 2025-04-18 20:03:23,350 [294] [ERROR] [gunicorn.error] Error handling request /api/v1/superuser/takeownership/NAMESPACE_NAME 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | Traceback (most recent call last): 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 3057, in execute_sql 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | cursor.execute(sql, params or ()) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | psycopg2.errors.InFailedSqlTransaction: current transaction is aborted, commands ignored until end of transaction block 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | During handling of the above exception, another exception occurred: 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | Traceback (most recent call last): 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/gunicorn/workers/base_async.py", line 55, in handle 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | self.handle_request(listener_name, req, client, addr) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/gunicorn/workers/ggevent.py", line 128, in handle_request 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | super().handle_request(listener_name, req, sock, addr) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/gunicorn/workers/base_async.py", line 108, in handle_request 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | respiter = self.wsgi(environ, resp.start_response) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask/app.py", line 2213, in __call__ 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return self.wsgi_app(environ, start_response) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py", line 183, in __call__ 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return self.app(environ, start_response) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask/app.py", line 2193, in wsgi_app 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | response = self.handle_exception(e) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask_restful/__init__.py", line 298, in error_router 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return original_handler(e) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask/app.py", line 2190, in wsgi_app 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | response = self.full_dispatch_request() 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask/app.py", line 1486, in full_dispatch_request 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | rv = self.handle_user_exception(e) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask_restful/__init__.py", line 298, in error_router 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return original_handler(e) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask/app.py", line 1484, in full_dispatch_request 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | rv = self.dispatch_request() 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask/app.py", line 1469, in dispatch_request 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/endpoints/decorators.py", line 285, in wrapper 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return func(*args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/auth/decorators.py", line 68, in wrapper 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return func(*args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/util/request.py", line 64, in wrapper 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return decorator(func)(*args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask_restful/utils/cors.py", line 35, in wrapped_function 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | resp = make_response(f(*args, **kwargs)) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/endpoints/csrf.py", line 71, in wrapper 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | resp = func(*args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask_restful/__init__.py", line 489, in wrapper 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | resp = resource(*args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask/views.py", line 109, in view 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return current_app.ensure_sync(self.dispatch_request)(**kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/flask_restful/__init__.py", line 604, in dispatch_request 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | resp = meth(*args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/endpoints/decorators.py", line 189, in wrapper 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return func(*args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/endpoints/api/__init__.py", line 555, in wrapped 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return func(*args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/endpoints/api/superuser.py", line 815, in post 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | log_action("take_ownership", authed_user.username, log_metadata) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/endpoints/api/__init__.py", line 624, in log_action 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | logs_model.log_action( 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/data/logs_model/table_logs_model.py", line 232, in log_action 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | model.log.log_action( 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/data/model/log.py", line 248, in log_action 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | account = User.get(User.username == user_or_organization_name).id 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/data/readreplica.py", line 174, in get 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return sq.get() 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 6741, in get 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return clone.execute(database)[0] 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 1845, in inner 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return method(self, database, *args, **kwargs) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 1916, in execute 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return self._execute(database) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 2087, in _execute 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | cursor = database.execute(self) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 3070, in execute 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | return self.execute_sql(sql, params, commit=commit) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/quay-registry/data/database.py", line 228, in execute_sql 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | cursor = super(RetryOperationalError, self).execute_sql(sql, params, commit) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 3064, in execute_sql 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | self.commit() 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 2831, in __exit__ 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | reraise(new_type, new_type(exc_value, *exc_args), traceback) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 183, in reraise 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | raise value.with_traceback(tb) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | File "/app/lib/python3.9/site-packages/peewee.py", line 3057, in execute_sql 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | cursor.execute(sql, params or ()) 2025-04-18T20:03:23.350983294Z gunicorn-web stdout | peewee.InternalError: current transaction is aborted, commands ignored until end of transaction block 2025-04-18T20:03:23.351256858Z gunicorn-web stdout | 2025-04-18 20:03:23,350 [294] [INFO] [gunicorn.access] - - [18/Apr/2025:20:03:23 +0000] "POST /api/v1/superuser/takeownership/NAMESPACE_NAME HTTP/1.0" 500 0 "-" "-"
We see the following in the database:
2025-04-18 20:03:23.347 GMT [3499429] ERROR: duplicate key value violates unique constraint "teammember_user_id_team_id" 2025-04-18 20:03:23.347 GMT [3499429] DETAIL: Key (user_id, team_id)=(1230, 529) already exists. 2025-04-18 20:03:23.347 GMT [3499429] STATEMENT: INSERT INTO "teammember" ("user_id", "team_id") VALUES (1230, 529) RETURNING "teammember"."id"
So the user is already member of the owners team in that namespace. Most likely this just needs a try/except block and that should be it. UI should not error out with a 500 on this issue.
Please check.