{"record":{"id":"26cbc03fbef788fe","repo":"dbt-labs/dbt-core","slug":"failed-to-write-to-stdout","errorCode":null,"errorMessage":"failed to write to stdout","messagePattern":"failed to write to stdout","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-common/src/tracing/layers/tui_layer.rs","lineNumber":260,"sourceCode":"                    skipped.seen_unit_test,\n                    true,\n                ));\n\n                // Clear the pending names and flags\n                skipped.pending_names.clear();\n                skipped.seen_test = false;\n                skipped.seen_unit_test = false;\n            }\n        },\n    );\n\n    // Emit the output after the span lock has been released to avoid possible deadlocks\n    if let Some(output) = output_to_emit {\n        tui.write_suspended(|| {\n            io::stdout()\n                .lock()\n                .write_all(format!(\"{}\\n\", output).as_bytes())\n                .expect(\"failed to write to stdout\");\n        });\n    }\n}\n\nfn node_evaluated_progress_status(\n    span_status: Option<&SpanStatus>,\n    ne: &NodeEvaluated,\n) -> Option<&'static str> {\n    match ne.node_outcome() {\n        NodeOutcome::Success if get_test_outcome(ne.into()) == Some(TestOutcome::Failed) => {\n            Some(\"failed\")\n        }\n        NodeOutcome::Success => Some(\"succeeded\"),\n        NodeOutcome::Error => Some(\"failed\"),\n        NodeOutcome::Canceled => Some(\"cancelled\"),\n        NodeOutcome::Skipped => match ne.node_skip_reason() {\n            NodeSkipReason::Cached => Some(\"reused\"),\n            NodeSkipReason::NoOp => Some(\"no-op\"),","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-common/src/tracing/layers/tui_layer.rs#L242-L278","documentation":"The TUI layer writes pending-skip output lines to stdout with write_all and unwraps with .expect(\"failed to write to stdout\"). Rust std write_all returns Err when the underlying stdout is closed or unwritable (e.g. broken pipe), and this expect turns that into a panic.","triggerScenarios":"emit_pending_skips fires on span end / node processed while stdout has been closed or its reader exited — e.g. `dbt ... | head`, redirection to a full disk, or a supervisor that closed the pipe.","commonSituations":"Piping dbt output into `head`/`less -F` that exits early, running dbt under CI systems that kill the log stream, or stdout redirected to a file on a full filesystem.","solutions":["Avoid piping dbt output to commands that exit early, or run without the TUI layer (use --log-format json/text with a stable sink)","Check disk space and that the output file/pipe target is writable","In code, handle io::Error instead of .expect — specifically ignore io::ErrorKind::BrokenPipe"],"exampleFix":"// before\nio::stdout()\n    .lock()\n    .write_all(format!(\"{}\\n\", output).as_bytes())\n    .expect(\"failed to write to stdout\");\n// after\nif let Err(e) = io::stdout().lock().write_all(format!(\"{}\\n\", output).as_bytes()) {\n    if e.kind() != io::ErrorKind::BrokenPipe {\n        eprintln!(\"failed to write to stdout: {e}\");\n    }\n}","handlingStrategy":"try-catch","validationCode":"// before relying on stdout, verify it is writable\nuse std::io::IsTerminal;\nif !io::stdout().is_terminal() {\n    eprintln!(\"stdout is redirected; ensure the consumer stays alive for the whole run\");\n}","typeGuard":null,"tryCatchPattern":"match io::stdout().lock().write_all(bytes) {\n    Ok(()) => {}\n    Err(e) if e.kind() == io::ErrorKind::BrokenPipe => { /* consumer gone; stop writing */ }\n    Err(e) => eprintln!(\"stdout write failed: {e}\"),\n}","preventionTips":["Do not pipe dbt output into commands that exit early (head, less -F)","Redirect to a file when output consumers may terminate early","Monitor disk space when redirecting large run logs"],"tags":["io","stdout","panic","broken-pipe"],"backgroundTag":"broken-pipe","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}