{"record":{"id":"2d644121779d8c59","repo":"dbt-labs/dbt-core","slug":"worker-threads-set-multiple-times","errorCode":null,"errorMessage":"`worker_threads` set multiple times.","messagePattern":"`worker_threads` set multiple times\\.","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/dbt-runtime-macros/src/entry.rs","lineNumber":144,"sourceCode":"    fn set_flavor(&mut self, runtime: syn::Lit, span: Span) -> Result<(), syn::Error> {\n        if self.flavor.is_some() {\n            return Err(syn::Error::new(span, \"`flavor` set multiple times.\"));\n        }\n\n        let runtime_str = parse_string(runtime, span, \"flavor\")?;\n        let runtime =\n            RuntimeFlavor::from_str(&runtime_str).map_err(|err| syn::Error::new(span, err))?;\n        self.flavor = Some(runtime);\n        Ok(())\n    }\n\n    fn set_worker_threads(\n        &mut self,\n        worker_threads: syn::Lit,\n        span: Span,\n    ) -> Result<(), syn::Error> {\n        if self.worker_threads.is_some() {\n            return Err(syn::Error::new(\n                span,\n                \"`worker_threads` set multiple times.\",\n            ));\n        }\n\n        let worker_threads = parse_int(worker_threads, span, \"worker_threads\")?;\n        if worker_threads == 0 {\n            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","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-runtime-macros/src/entry.rs#L126-L162","documentation":"Each #[tokio::main]/#[tokio::test] attribute may specify `worker_threads` at most once. The generated BuildConfig stores Option<worker_threads>; if set_flavor-style setter sees it is already Some, it returns a syn::Error pointing at the duplicate key. This guards against ambiguous configuration rather than silently picking one value.","triggerScenarios":"Writing #[tokio::main(flavor = \"multi_thread\", worker_threads = 4, worker_threads = 8)] — the same attribute key appears twice in the token stream passed to build_config.","commonSituations":"Merging two attribute lines by hand; a macro or code generator emitting the option twice; copy-paste of an attribute line leaving the old worker_threads behind.","solutions":["Remove the duplicate `worker_threads = N` key, keeping only one","If you need runtime-configurable thread counts, drop the attribute and build the runtime manually with tokio::runtime::Builder","Combine the two values into one choice before invoking the macro"],"exampleFix":"// before\n#[tokio::main(flavor = \"multi_thread\", worker_threads = 4, worker_threads = 8)]\nasync fn main() {}\n\n// after\n#[tokio::main(flavor = \"multi_thread\", worker_threads = 8)]\nasync fn main() {}","handlingStrategy":"validation","validationCode":"fn check_no_dupes(attr_src: &str, key: &str) -> Result<(), String> {\n    let n = attr_src.split(',').filter(|p| p.trim().starts_with(key)).count();\n    if n > 1 { Err(format!(\"`{key}` specified {n} times\")) } else { Ok(()) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep each attribute on one line to make duplicate keys visually obvious","Don't merge attribute arguments from multiple examples by hand","Search the attribute line (Ctrl-F) for the key before adding it again"],"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-14T11:17:12.474Z"}