summarylogtreecommitdiffstats
path: root/github-pr-4832.patch
blob: cce25dc5046bc8512c991aca381c33d77dd188ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
From 3275a99b1eacef7dfd9bc6a691ab1e3365134509 Mon Sep 17 00:00:00 2001
From: paipeng-quiver <pai@quiver.ai>
Date: Sun, 15 Feb 2026 00:33:33 +0100
Subject: [PATCH] fix: add missing PermissionDeniedError to litellm exceptions
 list

Fixes #4829

litellm added PermissionDeniedError which was not in aider's EXCEPTIONS
list, causing a ValueError crash during LiteLLMExceptions initialization:

  ValueError: PermissionDeniedError is in litellm but not in aider's
  exceptions list

This is the same class of bug reported in #4829 (where BadGatewayError
was missing in an older version). The root cause is that aider's
exception list must be kept in sync with litellm's exception classes.

Added PermissionDeniedError as non-retryable with a descriptive message,
and added a corresponding test.
---
 aider/exceptions.py            |  5 +++++
 tests/basic/test_exceptions.py | 21 +++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/aider/exceptions.py b/aider/exceptions.py
index 5cbd023cc4b..c9f3cc2716b 100644
--- a/aider/exceptions.py
+++ b/aider/exceptions.py
@@ -35,6 +35,11 @@ class ExInfo:
     ExInfo("JSONSchemaValidationError", True, None),
     ExInfo("NotFoundError", False, None),
     ExInfo("OpenAIError", True, None),
+    ExInfo(
+        "PermissionDeniedError",
+        False,
+        "The API provider denied access. Check your API key permissions.",
+    ),
     ExInfo(
         "RateLimitError",
         True,
diff --git a/tests/basic/test_exceptions.py b/tests/basic/test_exceptions.py
index 5f9c095f8b6..b0ee481dd59 100644
--- a/tests/basic/test_exceptions.py
+++ b/tests/basic/test_exceptions.py
@@ -65,6 +65,27 @@ def test_context_window_error():
     assert ex_info.retry is False
 
 
+def test_permission_denied_error():
+    """Test specific handling of PermissionDeniedError"""
+    ex = LiteLLMExceptions()
+    from litellm import PermissionDeniedError
+
+    import httpx
+
+    mock_request = httpx.Request("GET", "https://api.openai.com/v1/chat/completions")
+    mock_response = httpx.Response(status_code=403, request=mock_request)
+    perm_error = PermissionDeniedError(
+        message="Permission denied",
+        llm_provider="openai",
+        model="gpt-4",
+        response=mock_response,
+    )
+    ex_info = ex.get_ex_info(perm_error)
+    assert ex_info.name == "PermissionDeniedError"
+    assert ex_info.retry is False
+    assert "denied" in ex_info.description.lower()
+
+
 def test_openrouter_error():
     """Test specific handling of OpenRouter API errors"""
     ex = LiteLLMExceptions()