Hello everyone,
I’m encountering an issue with the Responses API in the TypeScript SDK when using function calling. The error I see is:
BadRequestError: 400 No tool output found for function call call_<ID>.
This is not a duplicate‑ID problem. I can confirm via the OpenAI history endpoint that both the function_call event and its corresponding function_call_output are present:
{
"data": [
{
"id": "…",
"type": "function_call",
"status": "completed",
"call_id": "call_ABC"
},
{
"id": "…",
"type": "function_call_output",
"call_id": "call_ABC",
"output": "{\"success\":true}"
},
{
"id": "msg_…",
"type": "message",
"content": [{"text":"Parameter applied"}]
}
]
}
But immediately after sending a new user message in the same session (using previous_response_id), the SDK still throws:
No tool output found for function call call_ABC.
Here’s my code example:
import OpenAI from "openai";
interface ChangeParamArgs {
param: string;
value: string;
}
async function changeParam({ param, value }: ChangeParamArgs): Promise<{ success: boolean }> {
console.log(`Changing parameter ${param} to ${value}`);
return { success: true };
}
async function main() {
const client = new OpenAI({ apiKey: "**key**" });
const resp1 = await client.responses.create({
model: "gpt-4o",
store: true,
instructions: "you are a helpful assistant that can change parameters",
tools: [
{
type: "function",
name: "change_param",
description: "Use this tool to change a parameter",
strict: false,
parameters: {
type: "object",
properties: {
value: {
type: "string",
description: "The new value for the parameter"
},
param: {
type: "string",
description: "The parameter to change"
}
},
required: [
"value",
"param"
]
}
}
],
input: [
{ role: "user", content: "change param mode from slow to fast" }
]
});
console.log("Assistant:", JSON.stringify(resp1.output[0], null, 2))
const callEvent = resp1.output.find(o => o.type === "function_call");
if (!callEvent) {
throw new Error("no function call event");
}
const args: ChangeParamArgs = JSON.parse(callEvent.arguments);
const result = await changeParam(args);
const resp2 = await client.responses.create({
model: "gpt-4o",
previous_response_id: resp1.id,
store: true,
input: [
{
type: "function_call",
call_id: callEvent.call_id,
name: callEvent.name,
arguments: callEvent.arguments
},
{
type: "function_call_output",
call_id: callEvent.call_id,
output: JSON.stringify(result)
}
]
});
console.log("Assistant:", JSON.stringify(resp2.output[0], null, 2))
const resp3 = await client.responses.create({
model: "gpt-4o",
previous_response_id: resp1.id,
store: true,
input: [
{ role: "user", content: "what is the mode now?" }
]
});
// error here
console.log("Assistant:", JSON.stringify(resp3.output[0], null, 2))
}
main().catch(console.error);
Questions:
- Is this a bug in the Responses API or the TS SDK?
- Can anyone share a working TS/Responses API example where the call/output chain truly persists across messages?
Thank you for any insights!