{"record":{"id":"65aee3b5600a3c7c","repo":"atuinsh/atuin","slug":"failed-printing-to-stdout-e","errorCode":null,"errorMessage":"failed printing to stdout: {e}","messagePattern":"failed printing to stdout: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin/src/command/client/init/bash.rs","lineNumber":56,"sourceCode":"    write_tmux_config(writer, options.tmux)?;\n    writeln!(writer, \"__atuin_bind_ctrl_r={bind_ctrl_r}\")?;\n    writeln!(writer, \"__atuin_bind_up_arrow={bind_up_arrow}\")?;\n    writeln!(writer, \"{}\", BASH.main)?;\n\n    #[cfg(feature = \"ai\")]\n    if options.enable_ai {\n        writeln!(writer, \"{}\", atuin_ai::shell::BASH_INIT)?;\n    }\n\n    writeln!(writer, \"}}\") // end include guard\n}\n\npub fn init_static(options: &StaticInitOptions<'_>) {\n    if let Err(e) = write_static_init(&mut io::stdout().lock(), options) {\n        // This function used to use `println!`, which panics on write failure with this same\n        // message. Using a locked `Stdout` object is faster, but `write!` returns an error rather\n        // than panicking, so we manually panic here to keep the same behavior.\n        panic!(\"failed printing to stdout: {e}\");\n    }\n}\n\npub async fn init(\n    aliases: AliasStore,\n    vars: VarStore,\n    options: &StaticInitOptions<'_>,\n) -> Result<()> {\n    init_static(options);\n\n    let aliases = atuin_dotfiles::shell::bash::alias_config(&aliases).await;\n    let vars = atuin_dotfiles::shell::bash::var_config(&vars).await;\n\n    println!(\"{aliases}\");\n    println!(\"{vars}\");\n\n    Ok(())\n}","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/atuinsh/atuin/blob/c0c717ab04c881764bcad4b3d169a507e2432643/crates/atuin/src/command/client/init/bash.rs#L38-L74","documentation":"The bash init script is written to stdout; because `write!` returns errors instead of panicking like `println!`, this explicit panic preserves the original panic behavior when stdout cannot be written.","triggerScenarios":"`atuin init bash` (via `init_static`) when stdout is closed, a broken pipe (e.g. piping to `head` or a exited process), or the fd is otherwise unwritable","commonSituations":"`atuin init bash | head -1`, redirecting stdout to a full disk or closed fd, running under a shell wrapper that closes stdout","solutions":["Avoid piping atuin init output to commands that close the pipe early","Check that stdout is writable and the disk is not full","Re-run the command with stdout attached to a terminal or a file"],"exampleFix":"// before\natuin init bash | head -5\n// after\natuin init bash > atuin-init.sh","handlingStrategy":"try-catch","validationCode":"// check stdout is writable before invoking\nif !std::io::stdout().is_terminal() && std::env::var(\"ATUIN_INIT_OUT\").is_err() {\n    eprintln!(\"stdout may not be writable; redirect output to a file\");\n}","typeGuard":null,"tryCatchPattern":"match Command::new(\"atuin\").args([\"init\", \"bash\"]).status() {\n    Ok(s) if s.success() => {}\n    Err(e) => eprintln!(\"atuin init failed: {e}\"),\n    _ => eprintln!(\"atuin init failed (stdout write error?)\"),\n}","preventionTips":["Don't pipe init output into commands that close the pipe early","Check disk space and fd health in scripts generating init output"],"tags":["stdout","io","panic","shell"],"backgroundTag":"broken-pipe","analyzedSha":"c0c717ab04c881764bcad4b3d169a507e2432643","analyzedAt":"2026-09-12T07:40:01.341Z","contentChangedAt":"2026-09-12T07:40:01.341Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}