{"record":{"id":"104e7a3670fb9212","repo":"dbt-labs/dbt-core","slug":"crate-set-multiple-times","errorCode":null,"errorMessage":"`crate` set multiple times.","messagePattern":"`crate` set multiple times\\.","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/dbt-runtime-macros/src/entry.rs","lineNumber":170,"sourceCode":"            return Err(syn::Error::new(span, \"`worker_threads` may not be 0.\"));\n        }\n        self.worker_threads = Some((worker_threads, span));\n        Ok(())\n    }\n\n    fn set_start_paused(&mut self, start_paused: syn::Lit, span: Span) -> Result<(), syn::Error> {\n        if self.start_paused.is_some() {\n            return Err(syn::Error::new(span, \"`start_paused` set multiple times.\"));\n        }\n\n        let start_paused = parse_bool(start_paused, span, \"start_paused\")?;\n        self.start_paused = Some((start_paused, span));\n        Ok(())\n    }\n\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","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-runtime-macros/src/entry.rs#L152-L188","documentation":"The `crate` attribute option overrides which crate path the macro-generated code refers to (useful when tokio is re-exported under a different name). It may be specified only once; set_crate_name returns a syn::Error if crate_name is already Some. The error message says `crate` even though the field is crate_name.","triggerScenarios":"#[tokio::main(crate = \"tokio\", crate = \"my_tokio\")] — passing the `crate` key twice in one attribute.","commonSituations":"Re-export setups where a wrapper crate re-exports tokio and both the wrapper and the developer add a `crate` argument; mechanical attribute merging.","solutions":["Specify the `crate = \"path\"` key exactly once with the correct re-export path","Remove the duplicate key, keeping the path that actually resolves tokio","If two crates need different paths, use separate entry functions"],"exampleFix":"// before\n#[tokio::main(crate = \"tokio\", crate = \"my_app::tokio\")]\nasync fn main() {}\n\n// after\n#[tokio::main(crate = \"my_app::tokio\")]\nasync fn main() {}","handlingStrategy":"validation","validationCode":"fn check_crate_arg_once(attr_src: &str) -> Result<(), String> {\n    let n = attr_src.matches(\"crate =\").count();\n    if n <= 1 { Ok(()) } else { Err(\"duplicate `crate` attribute arg\".into()) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set the tokio re-export path in exactly one place (e.g. a shared attribute or wrapper macro)","Confirm the path in `crate = \"...\"` actually resolves to the tokio crate","Avoid hand-editing generated attributes that already include `crate =`"],"tags":["rust","proc-macro","tokio","duplicate-key"],"backgroundTag":"conflicting-config-options","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}