From 2bb11adb4976169f2434ce72a6185cb189d83079 Mon Sep 17 00:00:00 2001 From: webtecnica <75556242+webtecnica@users.noreply.github.com> Date: Sat, 4 Jul 2026 15:51:58 -0300 Subject: [PATCH] fix: classify OpenRouter 'no tool use' 404 as model_not_found with fallback When OpenRouter routes to an endpoint that does not support tool/function calling, it returns HTTP 404 with the message 'No endpoints found that support tool use. Try disabling "browser_back".' The raw error body does not contain 'model not found' or any other _MODEL_NOT_FOUND_PATTERNS entry, so it falls through to FailoverReason.unknown with retryable=True. The retry loop wastes 3-5 attempts on the same deterministic rejection, then surfaces a confusing generic error instead of automatically failing over to a fallback model or provider. Adding the OpenRouter phrase to _MODEL_NOT_FOUND_PATTERNS classifies it as model_not_found (retryable=False, should_fallback=True), which triggers the client-error fast-fallback path in conversation_loop.py: the agent switches to a configured fallback model/provider before the user sees the error. Existing buffered guidance in conversation_loop.py (the 'support tool use' hint at line ~2967) remains intact and surfaces only if every fallback exhausts. --- agent/error_classifier.py | 9 +++++++++ package-lock.json | 26 -------------------------- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/agent/error_classifier.py b/agent/error_classifier.py index 3489c66c949..27311609de6 100644 --- a/agent/error_classifier.py +++ b/agent/error_classifier.py @@ -279,6 +279,15 @@ _MODEL_NOT_FOUND_PATTERNS = [ "no such model", "unknown model", "unsupported model", + # OpenRouter returns 404 with this message when none of the candidate + # endpoints for the selected model support tool/function calling. + # Classifying this as model_not_found triggers fallback to a different + # model or provider that does support tools. Without this entry the + # pattern falls through to ``unknown`` with ``retryable=True``, the + # retry loop burns all attempts on the same deterministic rejection, + # and the error surfaces as a confusing "model not found" message + # instead of automatically failing over. See PR #58446. + "no endpoints found that support tool use", ] # Request-validation patterns — the request is malformed and will fail diff --git a/package-lock.json b/package-lock.json index 16a531bd876..e964704c44f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1902,7 +1902,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=18" } @@ -1919,7 +1918,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -1936,7 +1934,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -1953,7 +1950,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -1970,7 +1966,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=18" } @@ -1987,7 +1982,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=18" } @@ -2004,7 +1998,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -2021,7 +2014,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -2038,7 +2030,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2055,7 +2046,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2072,7 +2062,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2089,7 +2078,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2106,7 +2094,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2123,7 +2110,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2140,7 +2126,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2157,7 +2142,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2174,7 +2158,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -2191,7 +2174,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -2208,7 +2190,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -2225,7 +2206,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -2242,7 +2222,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -2259,7 +2238,6 @@ "os": [ "openharmony" ], - "peer": true, "engines": { "node": ">=18" } @@ -2276,7 +2254,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=18" } @@ -2293,7 +2270,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -2310,7 +2286,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -2327,7 +2302,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" }