{"id":"a8950e2a7e221107","repo":"rust-lang/rust","slug":"aborting-due-to-z-treat-err-as-bug-1","errorCode":null,"errorMessage":"aborting due to `-Z treat-err-as-bug=1`","messagePattern":"aborting due to `-Z treat-err-as-bug=1`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_errors/src/lib.rs","lineNumber":1528,"sourceCode":"                    \"`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`\"\n                ).arg(\"level\", bug.level).format();\n                bug.sub(Note, msg, bug.span.primary_span().unwrap().into());\n            }\n            bug.level = Bug;\n\n            self.emit_diagnostic(bug, None);\n        }\n\n        // Panic with `DelayedBugPanic` to avoid \"unexpected panic\" messages.\n        panic::panic_any(DelayedBugPanic);\n    }\n\n    fn panic_if_treat_err_as_bug(&self) {\n        if self.treat_err_as_bug() {\n            let n = self.flags.treat_err_as_bug.map(|c| c.get()).unwrap();\n            assert_eq!(n, self.err_guars.len() + self.lint_err_guars.len());\n            if n == 1 {\n                panic!(\"aborting due to `-Z treat-err-as-bug=1`\");\n            } else {\n                panic!(\"aborting after {n} errors due to `-Z treat-err-as-bug={n}`\");\n            }\n        }\n    }\n}\n\nstruct DelayedDiagInner {\n    inner: DiagInner,\n    note: Backtrace,\n}\n\nimpl DelayedDiagInner {\n    fn with_backtrace(diagnostic: DiagInner, backtrace: Backtrace) -> Self {\n        DelayedDiagInner { inner: diagnostic, note: backtrace }\n    }\n\n    fn decorate(self) -> DiagInner {","sourceCodeStart":1510,"sourceCodeEnd":1546,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_errors/src/lib.rs#L1510-L1546","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nRUSTFLAGS=\"-Z treat-err-as-bug=1\" cargo build\n# after\ncargo build","handlingStrategy":"validation","validationCode":"// This panic is triggered by the -Z treat-err-as-bug=1 unstable flag.\n// Validate build configuration before invoking rustc:\nfn rustc_invocation_is_safe(args: &[String]) -> Result<(), String> {\n    for a in args {\n        if a.starts_with(\"-Z\") && a.contains(\"treat-err-as-bug\") {\n            return Err(format!(\n                \"refusing to invoke rustc with unstable flag {} (forces abort on first error)\",\n                a\n            ));\n        }\n    }\n    Ok(())\n}\n\n// before spawning rustc:\n// rustc_invocation_is_safe(&args)?;","typeGuard":"// Validate that the resolved rustc profile does not enable treat-err-as-bug.\nstruct RustcArgs { flags: Vec<String> }\n\nimpl RustcArgs {\n    fn treats_err_as_bug(&self) -> bool {\n        self.flags.iter().any(|f| {\n            f == \"-Ztreat-err-as-bug\"\n            || f.starts_with(\"-Ztreat-err-as-bug=\")\n            || f.starts_with(\"--treat-err-as-bug\")\n        })\n    }\n}","tryCatchPattern":"// rustc aborts the process here (not a Rust Result); catch it at the\n// subprocess boundary, not with try/catch in-process.\nlet output = std::process::Command::new(\"rustc\")\n    .args(&filtered_args)\n    .output()?;\n\nif output.status.code() == Some(134) /* SIGABRT */\n    || std::str::from_utf8(&output.stderr)\n        .map(|s| s.contains(\"treat-err-as-bug\"))\n        .unwrap_or(false)\n{\n    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());\n}","preventionTips":["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."],"tags":["compiler-internal","treat-err-as-bug","abort","diagnostic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}