{"record":{"id":"9c3ff17c755dc280","repo":"dbt-labs/dbt-core","slug":"failed-to-write-to-stderr","errorCode":null,"errorMessage":"failed to write to stderr","messagePattern":"failed to write to stderr","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-common/src/tracing/layers/tui_layer.rs","lineNumber":761,"sourceCode":"                        .expect(\"failed to write to stdout\");\n                }\n            }\n\n            // Print errors and warnings with header if any exist (on stderr)\n            if !delayed_messages.errors_and_warnings.is_empty() {\n                stderr\n                    .write_all(\n                        format!(\n                            \"\\n{}\\n\",\n                            format_delimiter(\n                                \" Errors and Warnings \",\n                                self.max_term_line_width,\n                                true\n                            )\n                        )\n                        .as_bytes(),\n                    )\n                    .expect(\"failed to write to stderr\");\n\n                for msg in &delayed_messages.errors_and_warnings {\n                    stderr\n                        .write_all(msg.message.as_bytes())\n                        .expect(\"failed to write to stderr\");\n                }\n            }\n\n            // Flush streams if we had any messages\n            if !delayed_messages.test_failures.is_empty()\n                || !delayed_messages.errors_and_warnings.is_empty()\n            {\n                stderr.flush().expect(\"failed to write to stderr\");\n                stdout.flush().expect(\"failed to write to stdout\");\n            }\n        });\n\n        // Then print the invocation summary","sourceCodeStart":743,"sourceCodeEnd":779,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-common/src/tracing/layers/tui_layer.rs#L743-L779","documentation":"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.","triggerScenarios":"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.","commonSituations":"Capturing only stdout while the stderr consumer exited; combined `2>&1 | head` pipelines; containers whose stderr pipe was closed by the orchestrator.","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"],"exampleFix":"// before\nstderr.write_all(msg.message.as_bytes()).expect(\"failed to write to stderr\");\n// after\nif let Err(e) = stderr.write_all(msg.message.as_bytes()) {\n    if e.kind() != io::ErrorKind::BrokenPipe {\n        eprintln!(\"failed to write to stderr: {e}\");\n    }\n}","handlingStrategy":"try-catch","validationCode":"// shell: test -w /dev/stderr && echo \"stderr writable\"","typeGuard":null,"tryCatchPattern":"if let Err(e) = stderr.write_all(bytes) {\n    if e.kind() != io::ErrorKind::BrokenPipe { eprintln!(\"stderr write failed: {e}\"); }\n}","preventionTips":["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"],"tags":["io","stderr","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"}