{"record":{"id":"e8d2e55f76d756ca","repo":"conductor-oss/conductor","slug":"openai-responses-api-call-failed","errorCode":null,"errorMessage":"OpenAI Responses API call failed: ","messagePattern":"OpenAI Responses API call failed: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/providers/openai/OpenAIResponsesChatModel.java","lineNumber":70,"sourceCode":" * converts the response back to Spring AI's {@link ChatResponse}.\n */\n@Slf4j\npublic class OpenAIResponsesChatModel implements ChatModel {\n\n    private final OpenAIResponsesApi responsesApi;\n\n    public OpenAIResponsesChatModel(OpenAIResponsesApi responsesApi) {\n        this.responsesApi = responsesApi;\n    }\n\n    @Override\n    public ChatResponse call(Prompt prompt) {\n        try {\n            ResponseRequest request = buildRequest(prompt);\n            ResponseResult result = responsesApi.createResponse(request);\n            return toSpringChatResponse(result);\n        } catch (IOException e) {\n            throw new RuntimeException(\"OpenAI Responses API call failed: \" + e.getMessage(), e);\n        }\n    }\n\n    private ResponseRequest buildRequest(Prompt prompt) throws JsonProcessingException {\n        List<Message> messages = prompt.getInstructions();\n        ChatOptions options = prompt.getOptions();\n\n        // Extract system messages → instructions field\n        String instructions = null;\n        List<Message> nonSystemMessages = new ArrayList<>();\n        for (Message msg : messages) {\n            if (msg.getMessageType() == MessageType.SYSTEM) {\n                // Concatenate multiple system messages\n                String sysText = ((SystemMessage) msg).getText();\n                instructions = instructions == null ? sysText : instructions + \"\\n\" + sysText;\n            } else {\n                nonSystemMessages.add(msg);\n            }","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/providers/openai/OpenAIResponsesChatModel.java#L52-L88","documentation":"OpenAIResponsesChatModel.call() wraps an IOException from OpenAIResponsesApi.createResponse() in a RuntimeException with message \"OpenAI Responses API call failed: \". This is the primary chat model for the OpenAI provider (using the newer /v1/responses endpoint, not /chat/completions). The IOException originates from error 219 (non-2xx HTTP) or a network failure.","triggerScenarios":"The OpenAI provider's chat model call(Prompt) is invoked and POST /v1/responses fails: 401 invalid key, 429 rate limit, 400 invalid model or parameters, model not available for the Responses API, or network error.","commonSituations":"Expired API key; using a model that doesn't support the Responses API (some older models only work with Chat Completions); rate limit on high-throughput chat tasks; network timeout on long context windows; reasoning-model parameter mismatch (temperature rejected by o-series — note the code already retries without temperature).","solutions":["Inspect getCause() for the IOException — its message includes the HTTP status and response body (see error 219).","Verify the model supports the Responses API (gpt-4o, gpt-4o-mini, o1, o3, o4-mini, gpt-5 series).","Check that the API key is valid and has access to the requested model.","For 400 errors mentioning temperature with o-series models, the code already auto-retries without temperature — if it still fails, check other unsupported parameters."],"exampleFix":"// before: using a model only available via Chat Completions with Responses API\n{\"model\": \"gpt-3.5-turbo\", \"prompt\": \"...\"}\n// after\n{\"model\": \"gpt-4o\", \"prompt\": \"...\"}","handlingStrategy":"retry","validationCode":"// Validate chat request and model before calling\nif (input.getModel() == null || input.getModel().isBlank()) {\n    throw new IllegalArgumentException(\"Model name is required\");\n}\n// Verify model supports the Responses API\nSet<String> responsesApiModels = Set.of(\n    \"gpt-4o\", \"gpt-4o-mini\", \"o1\", \"o1-mini\", \"o3\", \"o3-mini\", \"o4-mini\",\n    \"gpt-5\", \"gpt-5-mini\", \"gpt-5-nano\");\nString modelPrefix = input.getModel().split(\"-\")[0];\nif (!responsesApiModels.contains(input.getModel())\n    && !input.getModel().startsWith(\"o1\")\n    && !input.getModel().startsWith(\"o3\")\n    && !input.getModel().startsWith(\"o4\")\n    && !input.getModel().startsWith(\"gpt-4o\")\n    && !input.getModel().startsWith(\"gpt-5\")) {\n    log.warn(\"Model '{}' may not support the Responses API\", input.getModel());\n}","typeGuard":"null","tryCatchPattern":"try {\n    ChatResponse response = chatModel.call(prompt);\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof IOException io) {\n        String msg = io.getMessage();\n        if (msg.contains(\"429\") || msg.contains(\"500\") || msg.contains(\"503\") || msg.contains(\"529\")) {\n            return retryWithBackoff(() -> chatModel.call(prompt));\n        }\n        log.error(\"Responses API error: {}\", msg);\n    }\n    throw e;\n}","preventionTips":["Verify the model supports the Responses API before routing to the OpenAI provider.","Check the API key is valid and has access to the requested model.","The code auto-retries without temperature for o-series 400s — but verify other params aren't causing issues.","Implement retry with backoff for 429/5xx/529 (overloaded) responses."],"tags":["openai","chat-completion","responses-api","network","api-error","ai"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}