Jump to solution
Verify

The Fix

Adds support for using absolute URLs to override the base URL in ClientSession, resolving the AssertionError when using WSS URLs.

Based on closed aio-libs/aiohttp issue #10027 · PR/commit linked

Production note: Most teams hit this during upgrades or environment changes. Roll out with a canary and smoke critical endpoints (health, OpenAPI/docs) before 100%.

Jump to Verify Open PR/Commit
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@ +Added support for overriding the base URL with an absolute one in client sessions +-- by :user:`vivodi`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
repro.py
from aiohttp import ClientSession from asyncio import run from typing import * class DiscordWebSocket: session = lambda: ClientSession(base_url = "https://discord.com/api/v10/") connection = None # would likely be replaced by DiscordWebSocket.connect() @classmethod async def connect(cls) -> NoReturn: wss : Dict = await cls.get("gateway") # {"url": "wss://gateway.discord.gg"} async with cls.session() as session: response = await session.ws_connect(f"{wss['url']}/") # AssertionError return response # debug stuff lol @classmethod async def get(cls, endpoint : str) -> Dict: async with cls.session() as session: response = session.get(endpoint) return await response.json() async def main() -> NoReturn: print(f"{await DiscordWebSocket.connect() = }") run(main())
verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
fix.md
Option A — Apply the official fix\nAdds support for using absolute URLs to override the base URL in ClientSession, resolving the AssertionError when using WSS URLs.\nWhen NOT to use: This fix is not applicable if the base URL should not be overridden by absolute URLs.\n\n

Why This Fix Works in Production

  • Trigger: AssertionError
  • Mechanism: The assertion fails because an absolute URL is passed while a base URL is set in ClientSession
Production impact:
  • If left unfixed, the same config can fail only in production (env differences), causing startup failures or partial feature outages.

Why This Breaks in Prod

  • Shows up under Python 3.12 in real deployments (not just unit tests).
  • The assertion fails because an absolute URL is passed while a base URL is set in ClientSession
  • Surfaces as: File "...\aiohttp\client.py", line 467, in _build_url

Proof / Evidence

Discussion

High-signal excerpts from the issue thread (symptoms, repros, edge-cases).

“> The url in ws_connect() must be relative if base_url is set in ClientSession. Passing a absolute url in request calls to override base_url is…”
@webknjaz · 2024-11-24 · confirmation · source
“> Passing a absolute url in request calls to override base_url is not supported”
@Dreamsorcerer · 2024-11-30 · source
“The url in ws_connect() must be relative if base_url is set in ClientSession. Passing a absolute url in request calls to override base_url is not…”
@Cycloctane · 2024-11-24 · source
“> As a side note, the type annotations with this are incorrect in the example. The NoReturn means that they should hang forever. But main()…”
@webknjaz · 2024-11-24 · source

Failure Signature (Search String)

  • AssertionError

Error Message

Stack trace
error.txt
Error Message ------------- File "...\aiohttp\client.py", line 467, in _build_url assert not url.absolute ^^^^^^^^^^^^^^^^^ AssertionError
Stack trace
error.txt
Error Message ------------- python .\main.py Traceback (most recent call last): File "C:\Users\demo\OneDrive\Documents\python\test\main.py", line 32, in <module> run(main()) File "C:\Users\demo\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 194, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "C:\Users\demo\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\demo\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 687, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "C:\Users\demo\OneDrive\Documents\python\test\main.py", line 29, in main print(f"{await WebSocket.connect() = }") ^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\demo\OneDrive\Documents\python\test\main.py", line 16, in connect response = await session.ws_connect(str(URL(f"{wss['url']}/"))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\demo\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\client.py", line 1002, in _ws_connect resp = await self.request( ^^^^^^^^^^^^^^^^^^^ File "C:\Users\demo\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\client.py", line 535, in _request url = self._buil ... (truncated) ...

Minimal Reproduction

repro.py
from aiohttp import ClientSession from asyncio import run from typing import * class DiscordWebSocket: session = lambda: ClientSession(base_url = "https://discord.com/api/v10/") connection = None # would likely be replaced by DiscordWebSocket.connect() @classmethod async def connect(cls) -> NoReturn: wss : Dict = await cls.get("gateway") # {"url": "wss://gateway.discord.gg"} async with cls.session() as session: response = await session.ws_connect(f"{wss['url']}/") # AssertionError return response # debug stuff lol @classmethod async def get(cls, endpoint : str) -> Dict: async with cls.session() as session: response = session.get(endpoint) return await response.json() async def main() -> NoReturn: print(f"{await DiscordWebSocket.connect() = }") run(main())

Environment

  • Python: 3.12

What Broke

The application raises an AssertionError when trying to connect to a WSS URL.

Why It Broke

The assertion fails because an absolute URL is passed while a base URL is set in ClientSession

Fix Options (Details)

Option A — Apply the official fix

Adds support for using absolute URLs to override the base URL in ClientSession, resolving the AssertionError when using WSS URLs.

When NOT to use: This fix is not applicable if the base URL should not be overridden by absolute URLs.

Fix reference: https://github.com/aio-libs/aiohttp/pull/10074

Last verified: 2026-02-09. Validate in your environment.

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • This fix is not applicable if the base URL should not be overridden by absolute URLs.

Verify Fix

verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.

Did This Fix Work in Your Case?

Quick signal helps us prioritize which fixes to verify and improve.

Prevention

  • Capture the exact failing error string in logs and tests so you can reproduce via a minimal script.
  • Pin production dependencies and upgrade only with a reproducible test that hits the failing path.

Related Issues

No related fixes found.

Sources

We don’t republish the full GitHub discussion text. Use the links above for context.