{"id":"8d74526aaf604dc2","repo":"rust-lang/rust","slug":"aborting-after-n-errors-due-to-z-treat-err-as","errorCode":null,"errorMessage":"aborting after {n} errors due to `-Z treat-err-as-bug={n}`","messagePattern":"aborting after (.+?) errors due to `-Z treat-err-as-bug=(.+?)`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_errors/src/lib.rs","lineNumber":1530,"sourceCode":"                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 {\n        // We are at the `DiagInner`/`DiagCtxtInner` level rather than the\n        // usual `Diag`/`DiagCtxt` level, so we must construct `diag` in a","sourceCodeStart":1512,"sourceCodeEnd":1548,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_errors/src/lib.rs#L1512-L1548","documentation":"Sibling of the single-error case: panic_if_treat_err_as_bug fires when -Z treat-err-as-bug=N (N>1) is set and the recorded count of error-guaranteeing diagnostics reaches N. The panic intentionally aborts compilation to give a backtrace at the Nth error, used by compiler developers to investigate error-emission code paths.","triggerScenarios":"rustc invoked with -Z treat-err-as-bug=N where N>1, and self.flags.treat_err_as_bug.unwrap().get() equals err_guars.len()+lint_err_guars.len() at the panic site. The interpolated {n} in the message is that threshold.","commonSituations":"Compiler contributors setting treat-err-as-bug to a higher threshold to skip early, expected errors and break on a later one; leftover -Z flag in CI RUSTFLAGS; bootstrap profile unintentionally enabling debug flags.","solutions":["Remove or lower -Z treat-err-as-bug from RUSTFLAGS / config.toml / .cargo/config","If debugging: inspect the backtrace printed with the panic to find the Nth emission site","Verify no wrapper (rustup, bootstrap) is injecting the flag (rustc -vV + verbose cargo)"],"exampleFix":"# before\nRUSTFLAGS=\"-Z treat-err-as-bug=5\" cargo build\n# after\ncargo build","handlingStrategy":"validation","validationCode":"// Same trigger as 195 but the n-errors variant. Validate build args upfront.\nfn deny_treat_err_as_bug(args: &[String]) -> Result<(), String> {\n    for a in args {\n        if a == \"-Ztreat-err-as-bug\"\n            || a.starts_with(\"-Ztreat-err-as-bug=\")\n        {\n            return Err(format!(\n                \"abort-on-N-errors mode enabled by {}; remove for production\",\n                a\n            ));\n        }\n    }\n    Ok(())\n}\n\n// deny_treat_err_as_bug(&args)?;","typeGuard":"struct RustcFlags(Vec<String>);\n\nimpl RustcFlags {\n    fn abort_mode(&self) -> Option<Option<u32>> {\n        for f in &self.0 {\n            if f == \"-Ztreat-err-as-bug\" { return Some(Some(1)); }\n            if let Some(rest) = f.strip_prefix(\"-Ztreat-err-as-bug=\") {\n                let n = rest.parse::<u32>().ok()?;\n                return Some(Some(n));\n            }\n        }\n        None\n    }\n}","tryCatchPattern":"// Process-level boundary: this variant aborts after N errors; detect from status/stderr.\nlet out = std::process::Command::new(\"rustc\").args(&args).output()?;\nlet stderr = String::from_utf8_lossy(&out.stderr);\nif stderr.contains(\"-Z treat-err-as-bug=\") {\n    let n = stderr\n        .lines()\n        .find_map(|l| l.split(\"treat-err-as-bug=\").nth(1)?.parse::<u32>().ok());\n    return Err(format!(\n        \"rustc aborted after {} errors due to treat-err-as-bug; this is a rustc-dev flag. Remove it.\",\n        n.unwrap_or(0)\n    ));\n}","preventionTips":["Scan RUSTFLAGS and CARGO_ENCODED_RUSTFLAGS for treat-err-as-bug before CI runs.","Keep unstable -Z flags out of release/nightly CI matrixes; gate them to an explicit rustc-dev job.","Parse rustc --print=cfg or -C help to detect unsupported flag combinations early.","Distinguish exit 101 (normal compile error) from 134 (abort) in your build wrapper.","Cache the validated flag set per toolchain to avoid re-scanning every compile."],"tags":["compiler-internal","treat-err-as-bug","abort","diagnostic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}