rust-lang/rust · critical
aborting due to `-Z treat-err-as-bug=1`
Error message
aborting due to `-Z treat-err-as-bug=1`
What it means
Emitted by panic_if_treat_err_as_bug when the -Z treat-err-as-bug=1 flag is set and rustc has just recorded exactly one error guarantee. Instead of continuing to emit the error normally, the driver aborts via panic! so compiler developers get a backtrace at the point the error is raised. This is a developer-only instrumentation of the compiler, never enabled in a normal build.
Source
Thrown at compiler/rustc_errors/src/lib.rs:1528
"`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"
).arg("level", bug.level).format();
bug.sub(Note, msg, bug.span.primary_span().unwrap().into());
}
bug.level = Bug;
self.emit_diagnostic(bug, None);
}
// Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
panic::panic_any(DelayedBugPanic);
}
fn panic_if_treat_err_as_bug(&self) {
if self.treat_err_as_bug() {
let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();
assert_eq!(n, self.err_guars.len() + self.lint_err_guars.len());
if n == 1 {
panic!("aborting due to `-Z treat-err-as-bug=1`");
} else {
panic!("aborting after {n} errors due to `-Z treat-err-as-bug={n}`");
}
}
}
}
struct DelayedDiagInner {
inner: DiagInner,
note: Backtrace,
}
impl DelayedDiagInner {
fn with_backtrace(diagnostic: DiagInner, backtrace: Backtrace) -> Self {
DelayedDiagInner { inner: diagnostic, note: backtrace }
}
fn decorate(self) -> DiagInner {View on GitHub (pinned to 22057b88b0)
Solutions
- Remove -Z treat-err-as-bug (and any -Z treat-err-as-bug=1) from RUSTFLAGS / config.toml / .cargo/config if you are not debugging the compiler
- If you are debugging: read the panic backtrace, it points at the emission site of the first error
- Clear cached RUSTFLAGS in shell, cargo config, and bootstrap profile after switching off the debug flag
Example fix
# before RUSTFLAGS="-Z treat-err-as-bug=1" cargo build # after cargo build
Defensive patterns
Strategy: validation
Validate before calling
// This panic is triggered by the -Z treat-err-as-bug=1 unstable flag.
// Validate build configuration before invoking rustc:
fn rustc_invocation_is_safe(args: &[String]) -> Result<(), String> {
for a in args {
if a.starts_with("-Z") && a.contains("treat-err-as-bug") {
return Err(format!(
"refusing to invoke rustc with unstable flag {} (forces abort on first error)",
a
));
}
}
Ok(())
}
// before spawning rustc:
// rustc_invocation_is_safe(&args)?; Type guard
// Validate that the resolved rustc profile does not enable treat-err-as-bug.
struct RustcArgs { flags: Vec<String> }
impl RustcArgs {
fn treats_err_as_bug(&self) -> bool {
self.flags.iter().any(|f| {
f == "-Ztreat-err-as-bug"
|| f.starts_with("-Ztreat-err-as-bug=")
|| f.starts_with("--treat-err-as-bug")
})
}
} Try / catch
// rustc aborts the process here (not a Rust Result); catch it at the
// subprocess boundary, not with try/catch in-process.
let output = std::process::Command::new("rustc")
.args(&filtered_args)
.output()?;
if output.status.code() == Some(134) /* SIGABRT */
|| std::str::from_utf8(&output.stderr)
.map(|s| s.contains("treat-err-as-bug"))
.unwrap_or(false)
{
return Err("rustc aborted because treat-err-as-bug promoted a normal error to an abort. Remove -Z treat-err-as-bug for production builds.".into());
} Prevention
- Never pass -Z treat-err-as-bug (or treat-warnings-as-bug) in production/CI build profiles; it is a tool for rustc developers, not users.
- If you imported it from a Cargo profile, audit [profile.*] and RUSTFLAGS env for -Z flags.
- Strip -Z flags derived from RUSTC_BOOTSTRAP or nightly-only toolchains before releasing.
- Treat exit code 134 (SIGABRT) from rustc as a configuration bug, not a compile error.
- If you genuinely want fail-fast, use --deny warnings instead of treat-err-as-bug.
When it happens
Trigger: rustc is invoked with -Z treat-err-as-bug=1 (or treat-err-as-bug defaults are forced on) and the diagnostic context reaches the first error-guaranteeing diagnostic. The assertion n == err_guars + lint_err_guars must hold (n == 1 here), then panic! fires the single-error message.
Common situations: A rustc contributor debugging why a particular diagnostic fires; a tool that accidentally leaves -Z treat-err-as-bug on in RUSTFLAGS; passing -Z flags on stable (rejected earlier); stale RUSTFLAGS in a project after switching toolchains.
Related errors
- aborting after {n} errors due to `-Z treat-err-as-bug={n}`
- `NumScalableVectors(0)` is illformed
- `NumScalableVectors(N)` for N>8 is illformed
- argument to `panic!()` in a const context must have type `&s
- Failed to get parent for {child:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/a8950e2a7e221107.json.
Report an issue: GitHub.