Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions relay/channel/openai/relay_responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,19 @@ func OaiResponsesStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp
return
}
sendResponsesStreamData(c, streamResponse, data)

switch streamResponse.Type {
case "error", "response.error", "response.failed":
streamError := streamResponse.Error
if (len(streamError) == 0 || string(streamError) == "null") && streamResponse.Response != nil && streamResponse.Response.Error != nil {
if errorBytes, err := common.Marshal(streamResponse.Response.Error); err == nil {
streamError = errorBytes
}
}
if len(streamError) > 0 && string(streamError) != "null" {
sr.Error(fmt.Errorf("%s: %s", streamResponse.Type, streamError))
}
}
switch streamResponse.Type {
case "response.completed", "response.done":
if streamResponse.Response != nil {
Expand Down
1 change: 1 addition & 0 deletions relaykit/dto/openai_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ const (
type ResponsesStreamResponse struct {
Type string `json:"type"`
Response *OpenAIResponsesResponse `json:"response,omitempty"`
Error json.RawMessage `json:"error,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)openai_response\.go$|(^|/)relay_responses\.go$|expr\.md$|common/json\.go$' || true

echo
echo "== dto outline =="
ast-grep outline relaykit/dto/openai_response.go --view expanded | sed -n '1,220p' || true

echo
echo "== dto relevant lines =="
sed -n '340,410p' relaykit/dto/openai_response.go

echo
echo "== relay handler relevant lines =="
sed -n '70,130p' relay/channel/openai/relay_responses.go

echo
echo "== references to streamResponse.Error and Response.Error =="
rg -n "streamResponse\.Error|Response\.Error|type.*error|response\.error|Error.*struct|type.*Response" relaykit relay -g '*.go' | sed -n '1,220p'

Repository: QuantumNous/new-api

Length of output: 43863


🌐 Web query:

OpenAI Responses streaming top-level error event code message param documentation

💡 Result:

When using streaming with the OpenAI API, error handling occurs both at the initiation of the request and during the stream itself. Error Structure When an API error occurs, the error object consistently includes the following fields [1][2][3]: - code: A string identifying the specific type of error (e.g., 'rate_limit_exceeded', 'invalid_request_error') [4][1][5]. - message: A human-readable string explaining the error [4][1][2]. - param: A string identifying the specific parameter that caused the error, if applicable [4][1][2]. - type: A string categorizing the error (e.g., 'invalid_request_error', 'server_error') [1][2][5]. Streaming Error Handling 1. Request Initiation: Errors that occur before the stream begins (e.g., network issues, authentication errors, or invalid initial parameters) are thrown by the initial API call [6]. These should be caught using standard try-catch blocks surrounding the request initiation [7][8][6]. 2. Streaming Events: For streaming endpoints, such as the Responses API or Chat Completions, the API can emit dedicated error events during the stream [9][4][10]. - In the Responses API, an event with the type 'error' is explicitly emitted when a response fails [4]. This event contains the code, message, and param fields [4]. - If using the OpenAI SDKs, errors during iteration should be caught within the loop that processes the stream chunks [6]. If a stream is interrupted or fails to produce a valid response, the SDK may throw an internal error (e.g., 'OpenAIError') that also requires handling [11][12]. Best Practices - Wrap your request in a try-catch block to handle initial setup errors [7][6]. - When iterating through the stream, be prepared to catch exceptions that may occur due to connection drops or premature stream termination [6][12]. - Consult the official API reference for your specific endpoint, as streaming event schemas can vary between legacy and newer (e.g., Responses) APIs [9][4][10].

Citations:


🌐 Web query:

OpenAI Responses streaming response.error event schema top-level error

💡 Result:

In OpenAI streaming responses—particularly within the Responses API and structured streaming contexts—the error event follows a specific schema designed to communicate failure states mid-stream [1][2]. The standard schema for an error event in these streams is structured as follows [1][3]: { "type": "error", "sequence_number": , "error": { "type": "", "code": "<string|null>", "message": "", "param": "<string|object|null>" } } Key components include: type: Always set to "error" to identify the event type [1]. sequence_number: An integer representing the sequence position of the event [1]. error: An object containing the details of the failure [1][3]: - type: The category or classification of the error (e.g., "invalid_request_error", "server_error") [3]. - code: A specific error code string, or null if not applicable [1][3]. - message: A human-readable description of the error [1][3]. - param: The specific parameter associated with the error, which may be a string or an object depending on the error context [1][3]. It is important to distinguish this specific "error" event schema from general API errors, which may be raised by the SDK as exceptions (e.g., APIError, BadRequestError) when the request itself fails before or during the stream [4][5][6]. When using official SDKs, you can typically listen for these events via event emitters or stream iterators (e.g., event.type == "error" or.on("error",...)) to handle terminal states gracefully [2][7][8].

Citations:


🌐 Web query:

site:platform.openai.com Responses streaming events "error" code message param

💡 Result:

In the context of OpenAI APIs and general streaming (Server-Sent Events) architectures, errors occurring after a stream has already begun are typically handled by sending a specific error event before closing the connection [1]. For APIs following the OpenAI standard, errors in asynchronous or streaming contexts are structured as objects containing a code and a message [2]. Specifically: 1. Error Structure: Error objects typically consist of a code (a machine-readable string like server_error or rate_limit_exceeded) and a message (a human-readable description of the error) [2]. 2. Streaming Behavior: When a streaming request fails, the server often sends an event containing the error details in the data field—or occasionally terminates the stream abruptly after the final chunk—depending on the specific endpoint's implementation [1]. If you are developing your own streaming API and need to convey errors, it is recommended practice to: - Use the data field of the SSE event to send a JSON-encoded object [1]. - Include a specific type field (e.g., error) to distinguish it from data chunks [1]. - Structure the payload with code and message parameters to ensure consistent error handling for your clients [2]. Always verify the specific implementation details in your API's schema or documentation, as error reporting can vary significantly between different streaming protocols and individual service designs [2][1].

Citations:


🌐 Web query:

developers.openai.com resource reference responses streaming error code message param

💡 Result:

When streaming responses from the OpenAI API, error events are communicated through specific event types. According to the official documentation for the Responses API, an error event is indicated by the type: "error" property [1][2]. The expected structure for an error event includes the following parameters [1][2]: - code: A string representing the specific error code [1][2]. - message: A string containing the error message [1][2]. - param: A string identifying the parameter that caused the error, if applicable [1][2]. - sequence_number: A number indicating the sequence of the event [1][2]. However, developers have observed that the actual API response may sometimes return these details nested within an error object (e.g., { "type": "error", "error": { "code": "...", "message": "...", "param": "..." } }) rather than at the root level as initially documented [3]. If you encounter difficulty accessing these fields, it is recommended to inspect the raw response or the Patch object (in some SDKs) to retrieve them from the nested structure [3]. When handling streaming in your application, you should listen for the error event type to identify and handle these issues programmatically [4]. Additionally, for non-streaming requests or general API interaction, the API typically returns standard error objects containing code, message, type, and param fields [5][6]. If you are using the OpenAI Python SDK, it generally maps these error responses into specific exception classes (such as RateLimitError or APIError) by parsing the JSON response body [7][6].

Citations:


🌐 Web query:

OpenAI Responses API streaming events error event structure code message param type object

💡 Result:

In the OpenAI Responses API, the streaming error event is a specific event type emitted when an error occurs during the stream [1][2]. The documented structure for an error event is as follows [1][3]: { "type": "error", "code": "string", "message": "string", "param": "string", "sequence_number": number } Field details: - type: Always set to "error" [1][3]. - code: A string representing the error code [1][3]. - message: A string containing the error message [1][3]. - param: An optional string indicating the error parameter, if applicable [1][3]. - sequence_number: A number representing the sequence number of this event [1][3]. Note: There have been reports that the API service may intermittently return a nested error structure (e.g., {"error": {"code": "...", "message": "...",...}}) [4][5], which differs from the documented top-level format. Developers should implement robust parsing that can handle both the documented format and, if necessary, the nested structure [5]. Additionally, the Responses API also utilizes a response.failed event for when a response generation specifically fails, which includes the response object itself [1][6]. This should not be confused with the general transport or stream-level error event [6].

Citations:


Handle the top-level Responses API error event payload.

type: "error" stream events can carry top-level code, message, and param, so the current streamResponse.Error fallback only handles nested response.*error payloads. Add fields/raw fallback for top-level error events and construct streamError from them before calling sr.Error(...).

📍 Affects 2 files
  • relaykit/dto/openai_response.go#L389-L389 (this comment)
  • relay/channel/openai/relay_responses.go#L99-L109
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relaykit/dto/openai_response.go` at line 389, The Responses API stream error
handling must support top-level error event fields instead of only nested
response.error payloads. In relaykit/dto/openai_response.go, extend the response
DTO around Error with top-level code, message, and param fields or an equivalent
raw fallback; in relay/channel/openai/relay_responses.go, update the stream
response handling to construct streamError from those top-level values before
calling sr.Error(...), while preserving nested-error handling.

Source: MCP tools

Delta string `json:"delta,omitempty"`
Item *ResponsesOutput `json:"item,omitempty"`
// - response.function_call_arguments.delta
Expand Down