fix(providers): classify byte-size request limit errors as context-length-exceeded (#11173)

Co-authored-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
snowingfox
2026-08-12 22:24:33 +00:00
committed by GitHub
parent c16de3d972
commit 5751715df0
2 changed files with 91 additions and 0 deletions
+33
View File
@@ -175,6 +175,39 @@ pub fn is_context_length_exceeded_message(text: &str) -> bool {
.iter()
.any(|phrase| text_lower.contains(phrase));
let words = text_lower.split(|character: char| !character.is_ascii_alphanumeric());
let mentions_request = words.clone().any(|word| word == "request");
let mentions_bytes = words.clone().any(|word| matches!(word, "byte" | "bytes"));
let mentions_content_length = ["content length", "content-length"]
.iter()
.any(|phrase| text_lower.contains(phrase));
let mentions_request_data_size = [
"request size",
"requestsize",
"request body size",
"request payload size",
"payload size",
"body size",
]
.iter()
.any(|phrase| text_lower.contains(phrase));
let request_data_too_large = [
"request body is too large",
"request body too large",
"request payload is too large",
"request payload too large",
"payload is too large",
"payload too large",
]
.iter()
.any(|phrase| text_lower.contains(phrase));
let mentions_byte_limit = mentions_request_data_size
|| request_data_too_large
|| (mentions_content_length && (mentions_request || mentions_bytes));
if mentions_byte_limit && mentions_overflow {
return true;
}
mentions_prompt_input_tokens && mentions_limit && mentions_overflow
}
@@ -0,0 +1,58 @@
use goose_providers::errors::ProviderError;
use goose_providers::http_status::{
is_context_length_exceeded_message, map_http_error_to_provider_error,
};
use reqwest::StatusCode;
use serde_json::json;
#[test]
fn byte_size_limit_messages_classify_as_context_length_exceeded() {
let messages = [
"Server received a request which exceeds maximum allowed content length. RequestSize(bytes): 34021227, Limit(bytes): 33554432.",
"Request body size exceeds the maximum allowed limit",
"Request body is too large",
"Request payload too large",
"Content-Length exceeds the maximum allowed request size",
];
for message in messages {
assert!(
is_context_length_exceeded_message(message),
"expected context-length match for: {message}"
);
}
}
#[test]
fn byte_size_limit_bad_request_maps_to_context_length_exceeded() {
let message = "Server received a request which exceeds maximum allowed content length. RequestSize(bytes): 34021227, Limit(bytes): 33554432.";
let error = map_http_error_to_provider_error(
StatusCode::BAD_REQUEST,
Some(json!({ "error": { "message": message } })),
"https://example.com/v1/messages",
);
assert_eq!(
error,
ProviderError::ContextLengthExceeded(message.to_string())
);
}
#[test]
fn generic_length_errors_are_not_context_length_exceeded() {
let messages = [
"metadata length exceeds maximum allowed",
"temperature exceeds maximum allowed value",
"Invalid request body: temperature exceeds maximum allowed value",
"tools[0].description content length exceeds maximum allowed",
"response content length exceeds maximum allowed",
"max_tokens must be less than or equal to 4096",
];
for message in messages {
assert!(
!is_context_length_exceeded_message(message),
"expected generic bad request for: {message}"
);
}
}