[GH-ISSUE #92] oikb validate --deep crashes with cryptic TypeError: ('parser', <class 'module'>) on Windows #60

Open
opened 2026-10-18 21:13:59 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @Nemo08 on GitHub (Aug 3, 2026).
Original GitHub issue: https://github.com/open-webui/oikb/issues/92

Title

oikb validate --deep crashes with cryptic TypeError: ('parser', <class 'module'>) on Windows — actual cause is stale trio incompatible with Python 3.13's pathlib.Path.parser

Summary

On Windows, oikb validate --deep (and in fact any oikb command that constructs an httpx.Client) can fail with a confusing, non-actionable error:

Deep validation
  ✗ Cannot reach Open WebUI: ('parser', <class 'module'>)

This looks like a network/connectivity problem, but it isn't — httpx.Client() never even gets to make a request. The root cause is an environment issue (outdated trio), but oikb's error handling in cli.py swallows the real traceback and prints only str(e), which for multi-arg exceptions is just repr(e.args). This makes the message actively misleading for anyone trying to diagnose a "connectivity" failure that has nothing to do with the network.

Environment

  • OS: Windows (PowerShell)
  • Python: 3.13.x
  • oikb: 0.4.0
  • httpx: 0.28.1
  • httpcore: 1.0.9
  • trio: 0.23.1 (before fix) — pulled in transitively via selenium / trio-websocket, used by httpcore._synchronization for sync primitives

Root cause

httpcore._synchronization imports trio on Windows for its locking primitives. trio's _path.py defines trio.Path by wrapping every method of pathlib.Path/PurePath via a metaclass (AsyncAutoWrapperType.generate_forwards), iterating over pathlib.Path's class attributes.

Python 3.13 added a new class attribute to pathlib.PurePath: parser (a module reference, e.g. posixpath/ntpath, part of the new path-flavour abstraction). Older versions of trio (e.g. 0.23.1) assume every wrapped attribute is callable/descriptor-like and blow up when it encounters a bare module:

# trio/_path.py, generate_forwards()
raise TypeError(attr_name, type(attr))
# -> TypeError('parser', <class 'module'>)

This exception propagates all the way up through httpcore → httpx.Client.__init__ → oikb._make_client(), where cli.py catches it as a generic Exception and prints:

except Exception as e:
    click.echo(click.style(f"  ✗ Cannot reach Open WebUI: {e}", fg="red"))

Since the TypeError was raised with two positional args, str(e) renders as repr(e.args) — hence the odd ('parser', <class 'module'>) output, with zero indication that this is an import-time failure unrelated to networking.

Fix on the user side: pip install --upgrade trio (0.23.1 → 0.33.0 resolves it).

Reproduction

python -c "import httpx; httpx.Client()"

On an affected environment (Python 3.13 + trio < ~0.26) this raises the traceback below instead of returning silently.

Full traceback
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import httpx; httpx.Client()
  File "...\httpx\_client.py", line 688, in __init__
    self._transport = self._init_transport(...)
  File "...\httpx\_client.py", line 731, in _init_transport
    return HTTPTransport(...)
  File "...\httpx\_transports\default.py", line 150, in __init__
    import httpcore
  File "...\httpcore\__init__.py", line 1, in <module>
    from ._api import request, stream
  File "...\httpcore\_api.py", line 7, in <module>
    from ._sync.connection_pool import ConnectionPool
  File "...\httpcore\_sync\__init__.py", line 1, in <module>
    from .connection import HTTPConnection
  File "...\httpcore\_sync\connection.py", line 14, in <module>
    from .._synchronization import Lock
  File "...\httpcore\_synchronization.py", line 12, in <module>
    import trio
  File "...\trio\__init__.py", line 77, in <module>
    from ._path import Path as Path
  File "...\trio\_path.py", line 201, in <module>
    class Path(metaclass=AsyncAutoWrapperType):
  File "...\trio\_path.py", line 145, in __init__
    type(cls).generate_forwards(cls, attrs)
  File "...\trio\_path.py", line 162, in generate_forwards
    raise TypeError(attr_name, type(attr))
TypeError: ('parser', <class 'module'>)

Suggested fixes for oikb

None of this is oikb's bug per se (it's an upstream trio/Python 3.13 incompatibility), but oikb's error handling makes it very hard to diagnose. Suggestions, roughly in order of preference:

  1. In _make_client() / the validate --deep handler, catch import/construction errors from httpx.Client() separately and print the full exception type + traceback (or at least repr(e) instead of str(e)) so users can see it's a TypeError on import, not a connection failure.
  2. Consider whether httpcore's optional trio backend needs to be pulled in at all for oikb's use case (oikb only uses the sync httpx.Client, not httpx.AsyncClient) — if there's a way to avoid triggering the trio import path for sync-only usage, that would sidestep this class of issue entirely.
  3. Document a minimum trio version (or add trio>=0.26 as an explicit constraint) in pyproject.toml if httpcore/trio end up in the dependency tree on Windows, since older trio is incompatible with Python 3.13.
  4. At minimum, mention this failure mode in the troubleshooting docs — "Cannot reach Open WebUI: ('parser', <class 'module'>)" is a decent search-engine anchor for future users hitting the same thing.

Additional notes

Direct connectivity to Open WebUI was confirmed working the whole time (curl -i $OPEN_WEBUI_URL/health returned 200 OK) while oikb validate --deep reported "Cannot reach Open WebUI" — worth flagging explicitly in any fix/doc update that this message can be a false negative for network reachability.

Originally created by @Nemo08 on GitHub (Aug 3, 2026). Original GitHub issue: https://github.com/open-webui/oikb/issues/92 ## Title `oikb validate --deep` crashes with cryptic `TypeError: ('parser', <class 'module'>)` on Windows — actual cause is stale `trio` incompatible with Python 3.13's `pathlib.Path.parser` ## Summary On Windows, `oikb validate --deep` (and in fact any `oikb` command that constructs an `httpx.Client`) can fail with a confusing, non-actionable error: ``` Deep validation ✗ Cannot reach Open WebUI: ('parser', <class 'module'>) ``` This looks like a network/connectivity problem, but it isn't — `httpx.Client()` never even gets to make a request. The root cause is an environment issue (outdated `trio`), but oikb's error handling in `cli.py` swallows the real traceback and prints only `str(e)`, which for multi-arg exceptions is just `repr(e.args)`. This makes the message actively misleading for anyone trying to diagnose a "connectivity" failure that has nothing to do with the network. ## Environment - OS: Windows (PowerShell) - Python: 3.13.x - oikb: 0.4.0 - httpx: 0.28.1 - httpcore: 1.0.9 - trio: 0.23.1 (before fix) — pulled in transitively via `selenium` / `trio-websocket`, used by `httpcore._synchronization` for sync primitives ## Root cause `httpcore._synchronization` imports `trio` on Windows for its locking primitives. `trio`'s `_path.py` defines `trio.Path` by wrapping every method of `pathlib.Path`/`PurePath` via a metaclass (`AsyncAutoWrapperType.generate_forwards`), iterating over `pathlib.Path`'s class attributes. Python 3.13 added a new class attribute to `pathlib.PurePath`: `parser` (a module reference, e.g. `posixpath`/`ntpath`, part of the new path-flavour abstraction). Older versions of `trio` (e.g. 0.23.1) assume every wrapped attribute is callable/descriptor-like and blow up when it encounters a bare module: ```python # trio/_path.py, generate_forwards() raise TypeError(attr_name, type(attr)) # -> TypeError('parser', <class 'module'>) ``` This exception propagates all the way up through `httpcore` → `httpx.Client.__init__` → `oikb._make_client()`, where `cli.py` catches it as a generic `Exception` and prints: ```python except Exception as e: click.echo(click.style(f" ✗ Cannot reach Open WebUI: {e}", fg="red")) ``` Since the `TypeError` was raised with two positional args, `str(e)` renders as `repr(e.args)` — hence the odd `('parser', <class 'module'>)` output, with zero indication that this is an import-time failure unrelated to networking. **Fix on the user side:** `pip install --upgrade trio` (0.23.1 → 0.33.0 resolves it). ## Reproduction ```powershell python -c "import httpx; httpx.Client()" ``` On an affected environment (Python 3.13 + trio < ~0.26) this raises the traceback below instead of returning silently. <details> <summary>Full traceback</summary> ``` Traceback (most recent call last): File "<string>", line 1, in <module> import httpx; httpx.Client() File "...\httpx\_client.py", line 688, in __init__ self._transport = self._init_transport(...) File "...\httpx\_client.py", line 731, in _init_transport return HTTPTransport(...) File "...\httpx\_transports\default.py", line 150, in __init__ import httpcore File "...\httpcore\__init__.py", line 1, in <module> from ._api import request, stream File "...\httpcore\_api.py", line 7, in <module> from ._sync.connection_pool import ConnectionPool File "...\httpcore\_sync\__init__.py", line 1, in <module> from .connection import HTTPConnection File "...\httpcore\_sync\connection.py", line 14, in <module> from .._synchronization import Lock File "...\httpcore\_synchronization.py", line 12, in <module> import trio File "...\trio\__init__.py", line 77, in <module> from ._path import Path as Path File "...\trio\_path.py", line 201, in <module> class Path(metaclass=AsyncAutoWrapperType): File "...\trio\_path.py", line 145, in __init__ type(cls).generate_forwards(cls, attrs) File "...\trio\_path.py", line 162, in generate_forwards raise TypeError(attr_name, type(attr)) TypeError: ('parser', <class 'module'>) ``` </details> ## Suggested fixes for oikb None of this is oikb's bug per se (it's an upstream `trio`/Python 3.13 incompatibility), but oikb's error handling makes it very hard to diagnose. Suggestions, roughly in order of preference: 1. In `_make_client()` / the `validate --deep` handler, catch import/construction errors from `httpx.Client()` separately and print the full exception type + traceback (or at least `repr(e)` instead of `str(e)`) so users can see it's a `TypeError` on import, not a connection failure. 2. Consider whether `httpcore`'s optional `trio` backend needs to be pulled in at all for oikb's use case (oikb only uses the sync `httpx.Client`, not `httpx.AsyncClient`) — if there's a way to avoid triggering the trio import path for sync-only usage, that would sidestep this class of issue entirely. 3. Document a minimum `trio` version (or add `trio>=0.26` as an explicit constraint) in `pyproject.toml` if `httpcore`/`trio` end up in the dependency tree on Windows, since older `trio` is incompatible with Python 3.13. 4. At minimum, mention this failure mode in the troubleshooting docs — "Cannot reach Open WebUI: ('parser', <class 'module'>)" is a decent search-engine anchor for future users hitting the same thing. ## Additional notes Direct connectivity to Open WebUI was confirmed working the whole time (`curl -i $OPEN_WEBUI_URL/health` returned `200 OK`) while `oikb validate --deep` reported "Cannot reach Open WebUI" — worth flagging explicitly in any fix/doc update that this message can be a false negative for network reachability.
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
open-webui/oikb#60
No description provided.