Skip to content

[Bug] Forgot password does not send email in Docker deployment #235

@Atlas-SZ

Description

@Atlas-SZ

Pre-checks

Deployment Method

Docker

Steps to Reproduce

  1. Configure SMTP and reset-password related values in .env

  2. Start the backend with Docker Compose

  3. Run:

    docker compose exec backend env | grep -E '^(SYSTEM_|PUBLIC_BASE_URL|PASSWORD_RESET_)'

  4. Observe that nothing is printed, meaning the variables were not injected into the backend container

  5. Open the forgot-password page and submit a valid user email

  6. See the success message:

    If an account with that email exists, a password reset email has been sent.

  7. Check backend logs and see:

    RuntimeError: no running event loop

Expected vs Actual Behavior

Expected:

  • .env mail-related variables should be available inside the backend container
  • Submitting forgot-password for an active existing user should enqueue and send the reset email successfully
  • Backend logs should not show async background task errors

Actual:

  • SYSTEM_, PUBLIC_BASE_URL, and PASSWORD_RESET_ variables are not injected into the backend container by Docker Compose

  • Forgot-password still returns a success message

  • The email is not sent because the background email task crashes with:

    RuntimeError: no running event loop

Logs / Screenshots

atlas@iZ2zeczbe6wnqqbaio0jyhZ:/opt/code/mnt/Clawith$ docker compose exec backend env | grep -E '^(SYSTEM_|PUBLIC_BASE_URL|PASSWORD_RESET_)'
atlas@iZ2zeczbe6wnqqbaio0jyhZ:/opt/code/mnt/Clawith$ docker compose exec backend env | grep -E '^(SYSTEM_|PUBLIC_BASE_URL|PASSWORD_RESET_)'
atlas@iZ2zeczbe6wnqqbaio0jyhZ:/opt/code/mnt/Clawith$ vim docker-compose.yml 【我手动增加了 env】
atlas@iZ2zeczbe6wnqqbaio0jyhZ:/opt/code/mnt/Clawith$ docker compose up -d --force-recreate backend
WARN[0000] No services to build
[+] up 3/3
✔ Container clawith-redis-1 Healthy 11.1s
✔ Container clawith-postgres-1 Healthy 11.1s
✔ Container clawith-backend-1 Recreated 10.5s
atlas@iZ2zeczbe6wnqqbaio0jyhZ:/opt/code/mnt/Clawith$ docker compose exec backend env | grep -E '^(SYSTEM_|PUBLIC_BASE_URL|PASSWORD_RESET_)'
PASSWORD_RESET_TOKEN_EXPIRE_MINUTES=30
SYSTEM_SMTP_TIMEOUT_SECONDS=15

===================================

026-03-30 08:57:04 | INFO | 547efde8-788 | logging:callHandlers:1762 - 172.22.0.5:47202 - "POST /api/auth/forgot-password HTTP/1.0" 200
2026-03-30 08:57:04 | ERROR | 547efde8-788 | logging:callHandlers:1762 - Exception in ASGI application

Traceback (most recent call last):

File "/usr/local/bin/uvicorn", line 8, in
sys.exit(main())
│ │ └
│ └
└ <module 'sys' (built-in)>
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1485, in call
return self.main(*args, **kwargs)
│ │ │ └ {}
│ │ └ ()
│ └ <function Command.main at 0x75282974ee80>

File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1406, in main
rv = self.invoke(ctx)
│ │ └ <click.core.Context object at 0x752829b3b1a0>
│ └ <function Command.invoke at 0x75282974eb60>

File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1269, in invoke
return ctx.invoke(self.callback, **ctx.params)
│ │ │ │ │ └ {'host': '0.0.0.0', 'port': 8000, 'app': 'app.main:app', 'uds': None, 'fd': None, 'reload': False, 'reload_dirs': (), 'reload...
│ │ │ │ └ <click.core.Context object at 0x752829b3b1a0>
│ │ │ └ <function main at 0x7528295b0d60>
│ │ └
│ └ <function Context.invoke at 0x75282974dda0>
└ <click.core.Context object at 0x752829b3b1a0>
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 824, in invoke
return callback(*args, **kwargs)
│ │ └ {'host': '0.0.0.0', 'port': 8000, 'app': 'app.main:app', 'uds': None, 'fd': None, 'reload': False, 'reload_dirs': (), 'reload...
│ └ ()
└ <function main at 0x7528295b0d60>
File "/usr/local/lib/python3.12/site-packages/uvicorn/main.py", line 433, in main
run(
└ <function run at 0x7528297b0680>
File "/usr/local/lib/python3.12/site-packages/uvicorn/main.py", line 606, in run
server.run()
│ └ <function Server.run at 0x7528297aea20>
└ <uvicorn.server.Server object at 0x7528296bfc50>
File "/usr/local/lib/python3.12/site-packages/uvicorn/server.py", line 75, in run
return asyncio_run(self.serve(sockets=sockets), loop_factory=self.config.get_loop_factory())
│ │ │ │ │ │ └ <function Config.get_loop_factory at 0x7528297218a0>
│ │ │ │ │ └ <uvicorn.config.Config object at 0x7528296bffe0>
│ │ │ │ └ <uvicorn.server.Server object at 0x7528296bfc50>
│ │ │ └ None
│ │ └ <function Server.serve at 0x7528297aeac0>
│ └ <uvicorn.server.Server object at 0x7528296bfc50>
└ <function run at 0x752829b9a2a0>
File "/usr/local/lib/python3.12/asyncio/runners.py", line 195, in run
return runner.run(main)
│ │ └ <coroutine object Server.serve at 0x752829533ae0>
│ └ <function Runner.run at 0x7528299239c0>
└ <asyncio.runners.Runner object at 0x752829b330e0>
File "/usr/local/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
│ │ │ └ <Task pending name='Task-1' coro=<Server.serve() running at /usr/local/lib/python3.12/site-packages/uvicorn/server.py:79> wai...
│ │ └ <cyfunction Loop.run_until_complete at 0x75282961abc0>
│ └ <uvloop.Loop running=True closed=False debug=False>
└ <asyncio.runners.Runner object at 0x752829b330e0>

File "/usr/local/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 416, in run_asgi
result = await app( # type: ignore[func-returns-value]
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7528296bfb00>
File "/usr/local/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
return await self.app(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184367...
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <fastapi.applications.FastAPI object at 0x75282911f290>
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7528296bfb00>
File "/usr/local/lib/python3.12/site-packages/fastapi/applications.py", line 1159, in call
await super().call(scope, receive, send)
│ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184367...
│ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
└ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
File "/usr/local/lib/python3.12/site-packages/starlette/applications.py", line 90, in call
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184367...
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x75282455d730>
└ <fastapi.applications.FastAPI object at 0x75282911f290>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in call
raise exc
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in call
await self.app(scope, receive, _send)
│ │ │ │ └ <function ServerErrorMiddleware.call.._send at 0x7528182b16c0>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <starlette.middleware.cors.CORSMiddleware object at 0x7528245e6cf0>
└ <starlette.middleware.errors.ServerErrorMiddleware object at 0x75282455d730>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/cors.py", line 96, in call
await self.simple_response(scope, receive, send, request_headers=headers)
│ │ │ │ │ └ Headers({'host': 'claw.ai.clinicalservice.cn', 'x-real-ip': '172.22.0.1', 'x-forwarded-proto': 'http', 'connection': 'close',...
│ │ │ │ └ <function ServerErrorMiddleware.call.._send at 0x7528182b16c0>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <function CORSMiddleware.simple_response at 0x75282840d440>
└ <starlette.middleware.cors.CORSMiddleware object at 0x7528245e6cf0>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/cors.py", line 154, in simple_response
await self.app(scope, receive, send)
│ │ │ │ └ functools.partial(<bound method CORSMiddleware.send of <starlette.middleware.cors.CORSMiddleware object at 0x7528245e6cf0>>, ...
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <app.core.middleware.TraceIdMiddleware object at 0x7528245e73b0>
└ <starlette.middleware.cors.CORSMiddleware object at 0x7528245e6cf0>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/base.py", line 198, in call
raise app_exc
└ RuntimeError('no running event loop')
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/base.py", line 144, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
│ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..send_no_error at 0x7528181b8cc0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x75282449fa10>
└ <app.core.middleware.TraceIdMiddleware object at 0x7528245e73b0>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 63, in call
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
│ │ │ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..send_no_error at 0x7528181b8cc0>
│ │ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ │ │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ │ │ └ <starlette.requests.Request object at 0x752818432c90>
│ │ └ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x752824ee63c0>
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x75282449fa10>
└ <function wrap_app_handling_exceptions at 0x75282857d4e0>
File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
│ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818364cc0>
│ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
└ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x752824ee63c0>
File "/usr/local/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in call
await self.app(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818364cc0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <fastapi.routing.APIRouter object at 0x7528279c5160>
└ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x752824ee63c0>
File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 660, in call
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818364cc0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <bound method Router.app of <fastapi.routing.APIRouter object at 0x7528279c5160>>
└ <fastapi.routing.APIRouter object at 0x7528279c5160>
File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 680, in app
await route.handle(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818364cc0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <function Route.handle at 0x75282857e8e0>
└ APIRoute(path='/api/auth/forgot-password', name='forgot_password', methods=['POST'])
File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818364cc0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <function request_response..app at 0x7528246ef7e0>
└ APIRoute(path='/api/auth/forgot-password', name='forgot_password', methods=['POST'])
File "/usr/local/lib/python3.12/site-packages/fastapi/routing.py", line 134, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
│ │ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818364cc0>
│ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ │ └ <starlette.requests.Request object at 0x752818430680>
│ └ <function request_response..app..app at 0x752818365260>
└ <function wrap_app_handling_exceptions at 0x75282857d4e0>
File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
│ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818367600>
│ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
└ <function request_response..app..app at 0x752818365260>
File "/usr/local/lib/python3.12/site-packages/fastapi/routing.py", line 121, in app
await response(scope, receive, send)
│ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818367600>
│ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528183d3d80>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
└ <starlette.responses.JSONResponse object at 0x752824341430>
File "/usr/local/lib/python3.12/site-packages/starlette/responses.py", line 170, in call
await self.background()
│ └ <fastapi.background.BackgroundTasks object at 0x7528183ea5d0>
└ <starlette.responses.JSONResponse object at 0x752824341430>
File "/usr/local/lib/python3.12/site-packages/starlette/background.py", line 36, in call
await task()
└ <starlette.background.BackgroundTask object at 0x7528182e0800>
File "/usr/local/lib/python3.12/site-packages/starlette/background.py", line 23, in call
await run_in_threadpool(self.func, *self.args, **self.kwargs)
│ │ │ │ │ │ └ {}
│ │ │ │ │ └ <starlette.background.BackgroundTask object at 0x7528182e0800>
│ │ │ │ └ (<function send_password_reset_email at 0x75280bfb8c20>, 'iqinfei@163.com', 'qinfei', 'https://claw.ai.clinicalservice.cn/res...
│ │ │ └ <starlette.background.BackgroundTask object at 0x7528182e0800>
│ │ └ <function run_background_email_job at 0x75280bfb8e00>
│ └ <starlette.background.BackgroundTask object at 0x7528182e0800>
└ <function run_in_threadpool at 0x752828851d00>
File "/usr/local/lib/python3.12/site-packages/starlette/concurrency.py", line 32, in run_in_threadpool
return await anyio.to_thread.run_sync(func)
│ │ │ └ functools.partial(<function run_background_email_job at 0x75280bfb8e00>, <function send_password_reset_email at 0x75280bfb8c2...
│ │ └ <function run_sync at 0x7528296d9b20>
│ └ <module 'anyio.to_thread' from '/usr/local/lib/python3.12/site-packages/anyio/to_thread.py'>
└ <module 'anyio' from '/usr/local/lib/python3.12/site-packages/anyio/init.py'>
File "/usr/local/lib/python3.12/site-packages/anyio/to_thread.py", line 63, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
└ <function get_async_backend at 0x7528296ef100>
File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2518, in run_sync_in_worker_thread
return await future
└ <Future finished exception=RuntimeError('no running event loop')>
File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1002, in run
result = context.run(func, *args)

File "/app/app/services/system_email_service.py", line 159, in run_background_email_job
fire_and_forget(result)
│ └ <coroutine object send_password_reset_email at 0x752818352b00>
└ <function fire_and_forget at 0x75280bfb8d60>

File "/app/app/services/system_email_service.py", line 144, in fire_and_forget
task = asyncio.create_task(coro)
│ │ └ <coroutine object send_password_reset_email at 0x752818352b00>
│ └ <function create_task at 0x752829ae8e00>
└ <module 'asyncio' from '/usr/local/lib/python3.12/asyncio/init.py'>

File "/usr/local/lib/python3.12/asyncio/tasks.py", line 417, in create_task
loop = events.get_running_loop()
│ └
└ <module 'asyncio.events' from '/usr/local/lib/python3.12/asyncio/events.py'>

RuntimeError: no running event loop
2026-03-30 08:57:21 | INFO | f800b8ad-01a | app.core.middleware:dispatch:28 - --> POST /api/auth/forgot-password [client: 172.22.0.5]
2026-03-30 08:57:21 | INFO | f800b8ad-01a | app.core.middleware:dispatch:41 - <-- POST /api/auth/forgot-password 200 0.007s
2026-03-30 08:57:21 | INFO | f800b8ad-01a | logging:callHandlers:1762 - 172.22.0.5:42054 - "POST /api/auth/forgot-password HTTP/1.0" 200
2026-03-30 08:57:21 | ERROR | f800b8ad-01a | logging:callHandlers:1762 - Exception in ASGI application

Traceback (most recent call last):

File "/usr/local/bin/uvicorn", line 8, in
sys.exit(main())
│ │ └
│ └
└ <module 'sys' (built-in)>
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1485, in call
return self.main(*args, **kwargs)
│ │ │ └ {}
│ │ └ ()
│ └ <function Command.main at 0x75282974ee80>

File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1406, in main
rv = self.invoke(ctx)
│ │ └ <click.core.Context object at 0x752829b3b1a0>
│ └ <function Command.invoke at 0x75282974eb60>

File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1269, in invoke
return ctx.invoke(self.callback, **ctx.params)
│ │ │ │ │ └ {'host': '0.0.0.0', 'port': 8000, 'app': 'app.main:app', 'uds': None, 'fd': None, 'reload': False, 'reload_dirs': (), 'reload...
│ │ │ │ └ <click.core.Context object at 0x752829b3b1a0>
│ │ │ └ <function main at 0x7528295b0d60>
│ │ └
│ └ <function Context.invoke at 0x75282974dda0>
└ <click.core.Context object at 0x752829b3b1a0>
File "/usr/local/lib/python3.12/site-packages/click/core.py", line 824, in invoke
return callback(*args, **kwargs)
│ │ └ {'host': '0.0.0.0', 'port': 8000, 'app': 'app.main:app', 'uds': None, 'fd': None, 'reload': False, 'reload_dirs': (), 'reload...
│ └ ()
└ <function main at 0x7528295b0d60>
File "/usr/local/lib/python3.12/site-packages/uvicorn/main.py", line 433, in main
run(
└ <function run at 0x7528297b0680>
File "/usr/local/lib/python3.12/site-packages/uvicorn/main.py", line 606, in run
server.run()
│ └ <function Server.run at 0x7528297aea20>
└ <uvicorn.server.Server object at 0x7528296bfc50>
File "/usr/local/lib/python3.12/site-packages/uvicorn/server.py", line 75, in run
return asyncio_run(self.serve(sockets=sockets), loop_factory=self.config.get_loop_factory())
│ │ │ │ │ │ └ <function Config.get_loop_factory at 0x7528297218a0>
│ │ │ │ │ └ <uvicorn.config.Config object at 0x7528296bffe0>
│ │ │ │ └ <uvicorn.server.Server object at 0x7528296bfc50>
│ │ │ └ None
│ │ └ <function Server.serve at 0x7528297aeac0>
│ └ <uvicorn.server.Server object at 0x7528296bfc50>
└ <function run at 0x752829b9a2a0>
File "/usr/local/lib/python3.12/asyncio/runners.py", line 195, in run
return runner.run(main)
│ │ └ <coroutine object Server.serve at 0x752829533ae0>
│ └ <function Runner.run at 0x7528299239c0>
└ <asyncio.runners.Runner object at 0x752829b330e0>
File "/usr/local/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
│ │ │ └ <Task pending name='Task-1' coro=<Server.serve() running at /usr/local/lib/python3.12/site-packages/uvicorn/server.py:79> wai...
│ │ └ <cyfunction Loop.run_until_complete at 0x75282961abc0>
│ └ <uvloop.Loop running=True closed=False debug=False>
└ <asyncio.runners.Runner object at 0x752829b330e0>

File "/usr/local/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 416, in run_asgi
result = await app( # type: ignore[func-returns-value]
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7528296bfb00>
File "/usr/local/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
return await self.app(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184348...
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <fastapi.applications.FastAPI object at 0x75282911f290>
└ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7528296bfb00>
File "/usr/local/lib/python3.12/site-packages/fastapi/applications.py", line 1159, in call
await super().call(scope, receive, send)
│ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184348...
│ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
└ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
File "/usr/local/lib/python3.12/site-packages/starlette/applications.py", line 90, in call
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184348...
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x75282455d730>
└ <fastapi.applications.FastAPI object at 0x75282911f290>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in call
raise exc
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in call
await self.app(scope, receive, _send)
│ │ │ │ └ <function ServerErrorMiddleware.call.._send at 0x7528182b0400>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <starlette.middleware.cors.CORSMiddleware object at 0x7528245e6cf0>
└ <starlette.middleware.errors.ServerErrorMiddleware object at 0x75282455d730>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/cors.py", line 96, in call
await self.simple_response(scope, receive, send, request_headers=headers)
│ │ │ │ │ └ Headers({'host': 'claw.ai.clinicalservice.cn', 'x-real-ip': '172.22.0.1', 'x-forwarded-proto': 'http', 'connection': 'close',...
│ │ │ │ └ <function ServerErrorMiddleware.call.._send at 0x7528182b0400>
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <function CORSMiddleware.simple_response at 0x75282840d440>
└ <starlette.middleware.cors.CORSMiddleware object at 0x7528245e6cf0>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/cors.py", line 154, in simple_response
await self.app(scope, receive, send)
│ │ │ │ └ functools.partial(<bound method CORSMiddleware.send of <starlette.middleware.cors.CORSMiddleware object at 0x7528245e6cf0>>, ...
│ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7528184...
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <app.core.middleware.TraceIdMiddleware object at 0x7528245e73b0>
└ <starlette.middleware.cors.CORSMiddleware object at 0x7528245e6cf0>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/base.py", line 198, in call
raise app_exc
└ RuntimeError('no running event loop')
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/base.py", line 144, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
│ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..send_no_error at 0x7528182b0220>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x75282449fa10>
└ <app.core.middleware.TraceIdMiddleware object at 0x7528245e73b0>
File "/usr/local/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 63, in call
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
│ │ │ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..send_no_error at 0x7528182b0220>
│ │ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ │ │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ │ │ └ <starlette.requests.Request object at 0x752818434a10>
│ │ └ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x752824ee63c0>
│ └ <starlette.middleware.exceptions.ExceptionMiddleware object at 0x75282449fa10>
└ <function wrap_app_handling_exceptions at 0x75282857d4e0>
File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
│ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x7528183b2ac0>
│ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
└ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x752824ee63c0>
File "/usr/local/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in call
await self.app(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x7528183b2ac0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <fastapi.routing.APIRouter object at 0x7528279c5160>
└ <fastapi.middleware.asyncexitstack.AsyncExitStackMiddleware object at 0x752824ee63c0>
File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 660, in call
await self.middleware_stack(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x7528183b2ac0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <bound method Router.app of <fastapi.routing.APIRouter object at 0x7528279c5160>>
└ <fastapi.routing.APIRouter object at 0x7528279c5160>
File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 680, in app
await route.handle(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x7528183b2ac0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <function Route.handle at 0x75282857e8e0>
└ APIRoute(path='/api/auth/forgot-password', name='forgot_password', methods=['POST'])
File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
│ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x7528183b2ac0>
│ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ └ <function request_response..app at 0x7528246ef7e0>
└ APIRoute(path='/api/auth/forgot-password', name='forgot_password', methods=['POST'])
File "/usr/local/lib/python3.12/site-packages/fastapi/routing.py", line 134, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
│ │ │ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x7528183b2ac0>
│ │ │ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
│ │ └ <starlette.requests.Request object at 0x752818432a50>
│ └ <function request_response..app..app at 0x752818367880>
└ <function wrap_app_handling_exceptions at 0x75282857d4e0>
File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
│ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818367ba0>
│ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
└ <function request_response..app..app at 0x752818367880>
File "/usr/local/lib/python3.12/site-packages/fastapi/routing.py", line 121, in app
await response(scope, receive, send)
│ │ │ └ <function wrap_app_handling_exceptions..wrapped_app..sender at 0x752818367ba0>
│ │ └ <function BaseHTTPMiddleware.call..call_next..receive_or_disconnect at 0x7528182b0040>
│ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.0', 'server': ('172.22.0.4', 8000), 'c...
└ <starlette.responses.JSONResponse object at 0x7528184311c0>
File "/usr/local/lib/python3.12/site-packages/starlette/responses.py", line 170, in call
await self.background()
│ └ <fastapi.background.BackgroundTasks object at 0x7528182ee060>
└ <starlette.responses.JSONResponse object at 0x7528184311c0>
File "/usr/local/lib/python3.12/site-packages/starlette/background.py", line 36, in call
await task()
└ <starlette.background.BackgroundTask object at 0x7528182f3530>
File "/usr/local/lib/python3.12/site-packages/starlette/background.py", line 23, in call
await run_in_threadpool(self.func, *self.args, **self.kwargs)
│ │ │ │ │ │ └ {}
│ │ │ │ │ └ <starlette.background.BackgroundTask object at 0x7528182f3530>
│ │ │ │ └ (<function send_password_reset_email at 0x75280bfb8c20>, 'qinfei@clinicalservice.cn', 'csc_admin', 'https://claw.ai.clinicals...
│ │ │ └ <starlette.background.BackgroundTask object at 0x7528182f3530>
│ │ └ <function run_background_email_job at 0x75280bfb8e00>
│ └ <starlette.background.BackgroundTask object at 0x7528182f3530>
└ <function run_in_threadpool at 0x752828851d00>
File "/usr/local/lib/python3.12/site-packages/starlette/concurrency.py", line 32, in run_in_threadpool
return await anyio.to_thread.run_sync(func)
│ │ │ └ functools.partial(<function run_background_email_job at 0x75280bfb8e00>, <function send_password_reset_email at 0x75280bfb8c2...
│ │ └ <function run_sync at 0x7528296d9b20>
│ └ <module 'anyio.to_thread' from '/usr/local/lib/python3.12/site-packages/anyio/to_thread.py'>
└ <module 'anyio' from '/usr/local/lib/python3.12/site-packages/anyio/init.py'>
File "/usr/local/lib/python3.12/site-packages/anyio/to_thread.py", line 63, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
└ <function get_async_backend at 0x7528296ef100>
File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2518, in run_sync_in_worker_thread
return await future
└ <Future finished exception=RuntimeError('no running event loop')>
File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1002, in run
result = context.run(func, *args)

File "/app/app/services/system_email_service.py", line 159, in run_background_email_job
fire_and_forget(result)
│ └ <coroutine object send_password_reset_email at 0x75280bf5e9e0>
└ <function fire_and_forget at 0x75280bfb8d60>

File "/app/app/services/system_email_service.py", line 144, in fire_and_forget
task = asyncio.create_task(coro)
│ │ └ <coroutine object send_password_reset_email at 0x75280bf5e9e0>
│ └ <function create_task at 0x752829ae8e00>
└ <module 'asyncio' from '/usr/local/lib/python3.12/asyncio/init.py'>

File "/usr/local/lib/python3.12/asyncio/tasks.py", line 417, in create_task
loop = events.get_running_loop()
│ └
└ <module 'asyncio.events' from '/usr/local/lib/python3.12/asyncio/events.py'>

RuntimeError: no running event loop
2026-03-30 08:57:22 | INFO | b77abe81-ebc | app.core.middleware:dispatch:28 - --> GET /api/health [client: 127.0.0.1]

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions