dbt-labs/dbt-core · error
failed to write to stderr
Error message
failed to write to stderr
What it means
The invocation-end summary writes an "Errors and Warnings" header and each message to stderr with .expect("failed to write to stderr"). A stderr write failure (closed stream, broken pipe, full disk) panics.
Source
Thrown at crates/dbt-common/src/tracing/layers/tui_layer.rs:761
.expect("failed to write to stdout");
}
}
// Print errors and warnings with header if any exist (on stderr)
if !delayed_messages.errors_and_warnings.is_empty() {
stderr
.write_all(
format!(
"\n{}\n",
format_delimiter(
" Errors and Warnings ",
self.max_term_line_width,
true
)
)
.as_bytes(),
)
.expect("failed to write to stderr");
for msg in &delayed_messages.errors_and_warnings {
stderr
.write_all(msg.message.as_bytes())
.expect("failed to write to stderr");
}
}
// Flush streams if we had any messages
if !delayed_messages.test_failures.is_empty()
|| !delayed_messages.errors_and_warnings.is_empty()
{
stderr.flush().expect("failed to write to stderr");
stdout.flush().expect("failed to write to stdout");
}
});
// Then print the invocation summaryView on GitHub (pinned to 0267ce9170)
Solutions
- Ensure stderr is attached to a live sink (tty, file) for the whole run
- Avoid pipelines that close early on combined output; capture stderr to a file instead
- Handle the io::Error in code (skip BrokenPipe) instead of .expect
Example fix
// before
stderr.write_all(msg.message.as_bytes()).expect("failed to write to stderr");
// after
if let Err(e) = stderr.write_all(msg.message.as_bytes()) {
if e.kind() != io::ErrorKind::BrokenPipe {
eprintln!("failed to write to stderr: {e}");
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// shell: test -w /dev/stderr && echo "stderr writable"
Try / catch
if let Err(e) = stderr.write_all(bytes) {
if e.kind() != io::ErrorKind::BrokenPipe { eprintln!("stderr write failed: {e}"); }
} Prevention
- Don't combine streams with 2>&1 | head; capture stderr to a file
- Ensure the orchestrator keeps stderr open until exit
- Treat BrokenPipe as end-of-consumer, not a crash
When it happens
Trigger: handle_invocation_end sees non-empty delayed_messages.errors_and_warnings and writing the header or a message to stderr fails — e.g. `dbt 2>&1 | head`, detached terminal, or stderr redirected to an unwritable/full target.
Common situations: Capturing only stdout while the stderr consumer exited; combined `2>&1 | head` pipelines; containers whose stderr pipe was closed by the orchestrator.
Related errors
- failed to write to stdout
- failed to write header to stdout
- failed to write show data to stdout
- Schema not found for canonical FQN: {}
- `EnterGuard` values dropped out of order. Guards returned by
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/9c3ff17c755dc280.
Report an issue: GitHub.