swc-project/swc · error

failed to emit error: {e}

Error message

failed to emit error: {e}

What it means

Runtime panic in swc_common's EmitterWriter (crates/swc_common/src/errors/emitter.rs). After a diagnostic's primary message is rendered into a StyledBuffer, `emit_to_destination` writes it to the destination stream (stderr/stdout/file/buffer); if that write returns an I/O error, the emitter panics with `failed to emit error: {e}` instead of continuing. Rust ignores SIGPIPE by default, so a closed pipe surfaces here as an EPIPE write error.

Source

Thrown at crates/swc_common/src/errors/emitter.rs:1367

        } else {
            self.get_max_line_num(span, children).to_string().len()
        };

        match self.emit_message_default(span, message, code, level, max_line_num_len, false) {
            Ok(()) => {
                if !children.is_empty() {
                    let mut buffer = StyledBuffer::new();
                    if !self.short_message {
                        draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1);
                    }
                    match emit_to_destination(
                        &buffer.render(),
                        level,
                        &mut self.dst,
                        self.short_message,
                    ) {
                        Ok(()) => (),
                        Err(e) => panic!("failed to emit error: {e}"),
                    }
                }
                if !self.short_message {
                    for child in children {
                        let span = child.render_span.as_ref().unwrap_or(&child.span);
                        if let Err(e) = self.emit_message_default(
                            span,
                            child.styled_message(),
                            &None,
                            child.level,
                            max_line_num_len,
                            true,
                        ) {
                            panic!("failed to emit error: {e}")
                        }
                    }
                    for sugg in suggestions {
                        if let Err(e) =

View on GitHub (pinned to 5176682b65)

Solutions

  1. Avoid early-exiting readers in pipelines (buffer output, or read the full output before closing)
  2. Restore default SIGPIPE behavior so the process terminates cleanly instead of panicking: `unsafe { libc::signal(libc::SIGPIPE, libc::SIG_DFL) }`
  3. Give the Handler an emitter writing to a destination you control (in-memory buffer) and print it yourself with error handling

Example fix

// before
let handler = Handler::with_tty_emitter(true, false); // writes to stderr; panics on EPIPE

// after
let buffer = WritableDestination::buffer();
let handler = Handler::with_emitter(true, false, Box::new(EmitterWriter::new(buffer.clone())));
// ... after run: match buffer.try_into_inner() { Ok(s) => { let _ = write!(io::stderr(), "{s}"); }, Err(_) => {} }
Defensive patterns

Strategy: try-catch

Try / catch

let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    err.into_diagnostic(&handler).emit();
}));
if result.is_err() {
    // destination write failed: fall back to a plain eprintln and continue
    let _ = writeln!(io::stderr(), "warning: failed to render diagnostic");
}

Prevention

When it happens

Trigger: Running swc with diagnostics piped to a short-lived reader (e.g. `swc ... | head -1`) that closes the pipe; stderr/stdout redirected to a closed fd or full disk; a custom Destination whose writer fails.

Common situations: CLI usage in shell pipelines where the downstream command exits early; CI log capture on a full disk; wasm/embedded hosts providing a broken writable destination.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/c9c04a87133469ce. Report an issue: GitHub.