Bug Description
Python Workers using FastAPI throw NoGilError: Attempted to use PyProxy when Python GIL not held when multiple concurrent HTTP requests hit the same isolate. The error occurs in the runtime's preparePython/initPyInstance code path — not in application code.
Stack Trace
NoGilError: Attempted to use PyProxy when Python GIL not held
at throw_no_gil (pyodide-internal:generated/emscriptenSetup:20688:13)
at wasm://wasm/020fb45e:wasm-function[432]:0x117f9b
at python_getattr (pyodide-internal:generated/emscriptenSetup:23035:13)
at Object.get (pyodide-internal:generated/emscriptenSetup:23106:119)
at async preparePython (pyodide:python-entrypoint-helper:202:28)
at async initPyInstance (pyodide:python-entrypoint-helper:258:24)
at async Proxy.<anonymous> (pyodide:python-entrypoint-helper:300:36)
Reproduction
- Deploy a Python Worker with FastAPI that makes async HTTP calls
- Send 3-5 concurrent requests to different endpoints on the same worker
- Observe
NoGilError on some requests, with outcome exception
The error is more likely when:
- Requests involve CPU-bound work
- Multiple requests arrive within the same ~100ms window
- The isolate is handling concurrent requests in stateless execution mode
Environment
compatibility_date: 2025-12-01 NOTE I just bumped my compat date to 2026-04-01, so perhaps that will help too.
compatibility_flags: ["python_workers"]
- Execution model: stateless
- Observed in deployed staging environment (not local dev)
Analysis
The race condition appears to be in the isolate re-use logic. When a second request arrives while the first is awaiting I/O (GIL released), preparePython for the second request tries to access a Python proxy object, but the GIL acquisition fails — likely because the first request's coroutine is resuming or the V8 snapshot restoration leaves the GIL in an inconsistent state.
All application code uses async/await correctly (no threading, no blocking I/O). The error is entirely within pyodide-internal and python-entrypoint-helper.
Bug Description
Python Workers using FastAPI throw
NoGilError: Attempted to use PyProxy when Python GIL not heldwhen multiple concurrent HTTP requests hit the same isolate. The error occurs in the runtime'spreparePython/initPyInstancecode path — not in application code.Stack Trace
Reproduction
NoGilErroron some requests, with outcomeexceptionThe error is more likely when:
Environment
compatibility_date:2025-12-01NOTE I just bumped my compat date to2026-04-01, so perhaps that will help too.compatibility_flags:["python_workers"]Analysis
The race condition appears to be in the isolate re-use logic. When a second request arrives while the first is awaiting I/O (GIL released),
preparePythonfor the second request tries to access a Python proxy object, but the GIL acquisition fails — likely because the first request's coroutine is resuming or the V8 snapshot restoration leaves the GIL in an inconsistent state.All application code uses async/await correctly (no threading, no blocking I/O). The error is entirely within
pyodide-internalandpython-entrypoint-helper.