sigoden/aichat · error
{err}
Error message
{err} What it means
During streaming chat completions, the upstream provider/channel pushes an error as the first stream event (ResEvent::First(Some(err))). The server aborts the request with bail!("{err}"), surfacing the underlying provider error to the client before any content is streamed.
Solutions
- Read the interpolated message for the underlying provider error and fix that root cause first
- Verify the provider API key/credentials configured for the model's channel
- Confirm the requested model name exists on the provider
- Retry with a non-streaming request to get a clearer error payload
- Switch to a different provider/channel to isolate whether it is provider-side
Example fix
// before: err message obscures root cause
bail!("{err}");
// after: log full context and re-raise
error!("upstream first-event error: {err}");
bail!("{err}"); Defensive patterns
Strategy: try-catch
Validate before calling
// before calling: verify provider config
if (!apiKey || !model) throw new Error('missing model or apiKey'); Try / catch
try {
const stream = await client.chat.completions.create({ model, messages, stream: true });
} catch (e) {
// message is the upstream provider error; inspect and map
console.error('upstream stream error:', e.message);
} Prevention
- Validate provider credentials at startup
- Check model availability before streaming
- Keep a fallback provider/channel configured
When it happens
Trigger: Calling POST /v1/chat/completions with stream=true when the first event received on the channel is an error (e.g. the provider rejected the request, auth failed, or model unavailable).
Common situations: Upstream API key invalid or expired; selected model not available on the provider; provider returns an immediate error for the request body; proxy/channel misconfiguration.
Related errors
- Invalid response data
- Invalid response data
- Unrecognized message, message_type
- Invalid messages
- Failed to parse '.tools
AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09).
Data as JSON: /api/errors/9f896bc4acc5a2e4.
Report an issue: GitHub.
Appendix: source
Thrown at src/serve.rs:413
handler.done();
}
tokio::join!(
map_event(sse_rx, &tx, is_first.clone()),
chat_completions(
client.as_ref(),
&http_client,
&mut handler,
data,
&tx,
is_first
),
);
});
let first_event = rx.recv().await;
if let Some(ResEvent::First(Some(err))) = first_event {
bail!("{err}");
}
let shared: Arc<(String, String, i64, AtomicBool)> =
Arc::new((completion_id, model_name, created, AtomicBool::new(false)));
let stream = UnboundedReceiverStream::new(rx);
let stream = stream.filter_map(move |res_event| {
let shared = shared.clone();
async move {
let (completion_id, model, created, has_tool_calls) = shared.as_ref();
match res_event {
ResEvent::Text(text) => {
Some(Ok(create_text_frame(completion_id, model, *created, &text)))
}
ResEvent::ToolCalls(tool_calls) => {
has_tool_calls.store(true, Ordering::SeqCst);
Some(Ok(create_tool_calls_frame(
completion_id,
model,View on GitHub (pinned to 82976d349a)