{"record":{"id":"d423470905cbb82b","repo":"tokio-rs/tokio","slug":"unhandled-panic-set-multiple-times","errorCode":null,"errorMessage":"`unhandled_panic` set multiple times.","messagePattern":"`unhandled_panic` set multiple times\\.","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"tokio-macros/src/entry.rs","lineNumber":173,"sourceCode":"\n    fn set_crate_name(&mut self, name: syn::Lit, span: Span) -> Result<(), syn::Error> {\n        if self.crate_name.is_some() {\n            return Err(syn::Error::new(span, \"`crate` set multiple times.\"));\n        }\n        let name_path = parse_path(name, span, \"crate\")?;\n        self.crate_name = Some(name_path);\n        Ok(())\n    }\n\n    fn set_unhandled_panic(\n        &mut self,\n        unhandled_panic: syn::Lit,\n        span: Span,\n    ) -> Result<(), syn::Error> {\n        if self.unhandled_panic.is_some() {\n            return Err(syn::Error::new(\n                span,\n                \"`unhandled_panic` set multiple times.\",\n            ));\n        }\n\n        let unhandled_panic = parse_string(unhandled_panic, span, \"unhandled_panic\")?;\n        let unhandled_panic =\n            UnhandledPanic::from_str(&unhandled_panic).map_err(|err| syn::Error::new(span, err))?;\n        self.unhandled_panic = Some((unhandled_panic, span));\n        Ok(())\n    }\n\n    fn macro_name(&self) -> &'static str {\n        if self.is_test {\n            \"tokio::test\"\n        } else {\n            \"tokio::main\"\n        }\n    }\n","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/tokio-rs/tokio/blob/625954f365727668cb02d04172b34f1149637728/tokio-macros/src/entry.rs#L155-L191","documentation":"`set_unhandled_panic` (entry.rs:171) records the first `unhandled_panic = \"...\"` (one of `ignore` / `shutdown_runtime`, controlling behavior when a task panics) and rejects a second one. The option is only valid for the `current_thread` flavor.","triggerScenarios":"Writing `#[tokio::main(unhandled_panic = \"ignore\", unhandled_panic = \"shutdown_runtime\")]`.","commonSituations":"Copy-paste; iterating on panic policy and forgetting to remove the previous setting.","solutions":["Remove the duplicate `unhandled_panic`, keeping the single intended behavior."],"exampleFix":"// before\n#[tokio::main(flavor = \"current_thread\", unhandled_panic = \"ignore\", unhandled_panic = \"shutdown_runtime\")]\nasync fn main() {}\n\n// after\n#[tokio::main(flavor = \"current_thread\", unhandled_panic = \"shutdown_runtime\")]\nasync fn main() {}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set `unhandled_panic` at most once and only with `flavor = \"current_thread\"`.","Choose `ignore` to keep the runtime alive or `shutdown_runtime` to tear it down on task panic.","Document the chosen policy for your team."],"tags":["tokio","macros","compile-error","config","duplicate-option"],"backgroundTag":null,"analyzedSha":"625954f365727668cb02d04172b34f1149637728","analyzedAt":"2026-08-11T17:46:45.378Z","contentChangedAt":"2026-08-11T17:46:45.378Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}