dbt-labs/dbt-core · error

failed to write show data to stdout

Error message

failed to write show data to stdout

What it means

handle_show_data_output writes show-query content to a locked stdout with .expect('failed to write show data to stdout'), panicking on write failure. The `dbt show` results must reach the terminal, so the layer treats write failure as fatal. The write fails when stdout's consumer has vanished or the target is unwritable.

Source

Thrown at crates/dbt-common/src/tracing/layers/tui_layer.rs:1428

                        .write_all(format!("{}\n", header).as_bytes())
                        .expect("failed to write header to stdout");
                }

                // Print list item content (always — result payload survives quiet)
                stdout
                    .write_all(format!("{}\n", list_item.content).as_bytes())
                    .expect("failed to write to stdout");
            });
        }
    }

    fn handle_show_data_output(&self, show_data: &ShowDataOutput) {
        self.write_suspended(|| {
            let mut stdout = io::stdout().lock();

            stdout
                .write_all(format!("{}\n", show_data.content).as_bytes())
                .expect("failed to write show data to stdout");
        });
    }

    fn handle_show_result(&self, show_result: &ShowResult) {
        self.write_suspended(|| {
            let mut stdout = io::stdout().lock();

            if self.show_options.is_empty() {
                // Quiet mode: suppress decorative title, emit raw content only.
                // Mirrors dbt-core's ShowNode quiet=True behaviour where the
                // "Previewing node 'X':" header is dropped but the data is kept.
                stdout
                    .write_all(format!("{}\n", show_result.content).as_bytes())
                    .expect("failed to write show result to stdout");
            } else {
                let colored_title = BLUE.apply_to(&show_result.title);
                stdout
                    .write_all(format!("\n{}\n{}\n", colored_title, show_result.content).as_bytes())

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Pipe into tee to a file rather than commands that exit early
  2. Check disk space/quota on the redirect target
  3. Keep the capturing harness alive until dbt exits
  4. Make the write non-fatal (warn and continue) instead of .expect

Example fix

// before
.expect("failed to write show data to stdout");
// after
if let Err(e) = stdout.write_all(format!("{}\n", show_data.content).as_bytes()) {
    eprintln!("warning: could not write show data: {e}");
}
Defensive patterns

Strategy: try-catch

Validate before calling

# preflight disk space and descriptor before show
df -h . && dbt show --inline 'select 1' > show_out.txt 2>&1

Type guard

fn stdout_writable() -> bool {
    use std::io::Write;
    io::stdout().flush().is_ok()
}

Try / catch

// detect failure and fall back to file output
dbt show --inline 'select 1' 2>err.log || { grep -q 'failed to write show data to stdout' err.log && dbt show --inline 'select 1' > out.txt; }

Prevention

When it happens

Trigger: A ShowDataOutput record arrives via on_log_record and write_all fails: pipe reader exited, pty closed, or redirected file cannot accept data (ENOSPC).

Common situations: `dbt show ... | head` truncating consumers; running under a wrapper that closed stdout; disk-quota errors when redirecting show output.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/6cf5d97b0d70aca6. Report an issue: GitHub.