Summary
When using the hosted ChatKit widget and returning tool output via onClientTool, the widget internally attempts to POST to:
https://api.openai.com/v1/chatkit/conversation
…with a type:
threads.add_client_tool_output" event.
However, that request is blocked by OpenAI API due to missing CORS headers, even though I am not manually calling fetch(…).
Error shown:
Access to fetch at ‘https://api.openai.com/v1/chatkit/conversation’ from origin ‘https://cdn.platform.openai.com’ has been blocked by CORS policy:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
Expected Behavior
Returning { success: true, … } from onClientTool should safely forward tool result to the thread without triggering CORS.
Actual Behavior
The widget makes this internal request (simplified):
{
“type”: “threads.add_client_tool_output”,
“params”: {
"thread_id": "cthr\_...",
"result": { "success": true, "weather": { ... } }
}
}
And it fails with:
CORS: No ‘Access-Control-Allow-Origin’
net::ERR_FAILED 500
Minimal Reproduction
onClientTool: async (invocation) => {
if (invocation.name === “get_weather”) {
const weather = {
location: {
name: "Québec",
region: "Quebec",
country: "Canada",
latitude: 46.81228,
longitude: -71.21454,
timezone: "America/Toronto"
},
current: {
time: "2025-10-08T11:45",
temperatureCelsius: 12.7,
temperatureFahrenheit: 55,
apparentTemperatureCelsius: 9.3,
apparentTemperatureFahrenheit: 49,
relativeHumidity: 65,
windSpeedKph: 17.3,
weatherCode: 1,
description: "Mainly clear"
}
};
// ✅ Per documentation: Just return the tool result
return { success: true, weather };
}
}
No manual fetch(…) is performed. The widget itself is triggering the failing request.


