BloopAI/vibe-kanban · error
Raw stream should only have Stdout/Stderr/Finished
Error message
Raw stream should only have Stdout/Stderr/Finished
What it means
In handle_raw_logs_ws, the raw execution-process log stream is mapped to WebSocket messages. Only Stdout, Stderr, and Finished are expected from the raw channel; any other LogMsg variant hits `unreachable!("Raw stream should only have Stdout/Stderr/Finished")`. This asserts the raw log channel's contract — e.g. if the upstream log source starts emitting JsonPatch or other control variants, the handler panics.
Source
Thrown at crates/server/src/routes/execution_processes.rs:102
}
};
let counter = Arc::new(AtomicUsize::new(0));
let mut stream = raw_stream.map_ok({
let counter = counter.clone();
move |m| match m {
LogMsg::Stdout(content) => {
let index = counter.fetch_add(1, Ordering::SeqCst);
let patch = ConversationPatch::add_stdout(index, content);
LogMsg::JsonPatch(patch).to_ws_message_unchecked()
}
LogMsg::Stderr(content) => {
let index = counter.fetch_add(1, Ordering::SeqCst);
let patch = ConversationPatch::add_stderr(index, content);
LogMsg::JsonPatch(patch).to_ws_message_unchecked()
}
LogMsg::Finished => LogMsg::Finished.to_ws_message_unchecked(),
_ => unreachable!("Raw stream should only have Stdout/Stderr/Finished"),
}
});
loop {
tokio::select! {
item = stream.next() => {
match item {
Some(Ok(msg)) => {
if socket.send(msg).await.is_err() {
break;
}
}
Some(Err(e)) => {
tracing::error!("stream error: {}", e);
break;
}
None => break,
}View on GitHub (pinned to 4deb7eca8f)
Solutions
- Inspect the backtrace/log to identify the unexpected LogMsg variant and either filter it out before mapping or add an explicit arm.
- Ensure the raw logs channel is only fed by raw stdout/stderr/finished producers, not the JsonPatch-producing normalized stream.
- Replace the wildcard `_` arm with an explicit enumeration so compilation fails when new LogMsg variants are added.
Example fix
// before
_ => unreachable!("Raw stream should only have Stdout/Stderr/Finished"),
// after
LogMsg::JsonPatch(_) => continue, // or handle explicitly
_ => unreachable!("Raw stream should only have Stdout/Stderr/Finished"), Defensive patterns
Strategy: try-catch
Validate before calling
// Producer side: only emit raw variants assert!(matches!(msg, LogMsg::Stdout(_)|LogMsg::Stderr(_)|LogMsg::Finished));
Try / catch
match log_msg {
LogMsg::Stdout(_) | LogMsg::Stderr(_) | LogMsg::Finished => { /* map */ }
other => {
tracing::warn!("unexpected raw log variant: {:?}", other);
// skip instead of panicking
}
} Prevention
- Keep the raw log channel separate from JsonPatch-producing normalized streams
- Enumerate variants explicitly instead of a `_` catch-all so new LogMsg kinds break compilation
- On protocol changes to LogMsg, audit all WS endpoints including raw logs
When it happens
Trigger: A LogMsg arrives on the raw logs stream that is not Stdout/Stderr/Finished — e.g. the log broadcaster emits JsonPatch or control messages on the raw channel, or a new LogMsg variant was added without updating this mapping.
Common situations: Executor changes that route structured (JsonPatch) output through the raw stream; a shared log channel reused for both normalized and raw subscribers; adding a LogMsg variant upstream without touching this endpoint.
Related errors
- Default profiles v3 JSON is invalid
- request_id called for unsupported request variant
- handled non-session commands earlier
- validated digest hour
- date overflow for digest schedule
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/f0084fd1b66c8c2f.
Report an issue: GitHub.