Unverified Commit 6a69ef4f authored by heisenberglit's avatar heisenberglit Committed by GitHub
Browse files

fix: cryptic error message for empty messages list in /chat/completions #2067 (#2067)

parent 2c642fd0
...@@ -413,6 +413,9 @@ async fn chat_completions( ...@@ -413,6 +413,9 @@ async fn chat_completions(
// and early return a 501 NOT_IMPLEMENTED status code. Otherwise, proceeed. // and early return a 501 NOT_IMPLEMENTED status code. Otherwise, proceeed.
validate_chat_completion_unsupported_fields(&request)?; validate_chat_completion_unsupported_fields(&request)?;
// Handle required fields like messages shouldn't be empty.
validate_chat_completion_required_fields(&request)?;
// Apply template values if present // Apply template values if present
if let Some(template) = template { if let Some(template) = template {
if request.inner.model.is_empty() { if request.inner.model.is_empty() {
...@@ -558,6 +561,23 @@ pub fn validate_chat_completion_unsupported_fields( ...@@ -558,6 +561,23 @@ pub fn validate_chat_completion_unsupported_fields(
Ok(()) Ok(())
} }
/// Validates that required fields are present and valid in the chat completion request
pub fn validate_chat_completion_required_fields(
request: &NvCreateChatCompletionRequest,
) -> Result<(), ErrorResponse> {
let inner = &request.inner;
if inner.messages.is_empty() {
return Err(ErrorMessage::from_http_error(HttpError {
code: 400,
message: "The 'messages' field cannot be empty. At least one message is required."
.to_string(),
}));
}
Ok(())
}
/// OpenAI Responses Request Handler /// OpenAI Responses Request Handler
/// ///
/// This method will handle the incoming request for the /v1/responses endpoint. /// This method will handle the incoming request for the /v1/responses endpoint.
...@@ -1009,6 +1029,10 @@ mod tests { ...@@ -1009,6 +1029,10 @@ mod tests {
Role as ResponseRole, ServiceTier, TextConfig, TextResponseFormat, ToolChoice, Role as ResponseRole, ServiceTier, TextConfig, TextResponseFormat, ToolChoice,
ToolChoiceMode, Truncation, ToolChoiceMode, Truncation,
}; };
use async_openai::types::{
ChatCompletionRequestMessage, ChatCompletionRequestUserMessage,
ChatCompletionRequestUserMessageContent, CreateChatCompletionRequest,
};
use super::*; use super::*;
use crate::discovery::ModelManagerError; use crate::discovery::ModelManagerError;
...@@ -1195,4 +1219,44 @@ mod tests { ...@@ -1195,4 +1219,44 @@ mod tests {
assert!(result.is_some(), "Expected rejection for `{field}`"); assert!(result.is_some(), "Expected rejection for `{field}`");
} }
} }
#[test]
fn test_validate_chat_completion_required_fields_empty_messages() {
let request = NvCreateChatCompletionRequest {
inner: CreateChatCompletionRequest {
model: "test-model".to_string(),
messages: vec![],
..Default::default()
},
nvext: None,
};
let result = validate_chat_completion_required_fields(&request);
assert!(result.is_err());
if let Err((status, error_response)) = result {
assert_eq!(status, StatusCode::BAD_REQUEST);
assert_eq!(
error_response.error,
"The 'messages' field cannot be empty. At least one message is required."
);
}
}
#[test]
fn test_validate_chat_completion_required_fields_with_messages() {
let request = NvCreateChatCompletionRequest {
inner: CreateChatCompletionRequest {
model: "test-model".to_string(),
messages: vec![ChatCompletionRequestMessage::User(
ChatCompletionRequestUserMessage {
content: ChatCompletionRequestUserMessageContent::Text("Hello".to_string()),
name: None,
},
)],
..Default::default()
},
nvext: None,
};
let result = validate_chat_completion_required_fields(&request);
assert!(result.is_ok());
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment