dbt-labs/dbt-core · error · syn::Error
`worker_threads` may not be 0.
Error message
`worker_threads` may not be 0.
What it means
After parsing `worker_threads` as an integer, the macro rejects a value of 0 because a multi-thread runtime must have at least one worker thread; tokio's Builder would panic or misbehave with zero workers, so the macro fails at compile time instead. The check lives in set_worker_threads right after parse_int.
Source
Thrown at crates/dbt-runtime-macros/src/entry.rs:152
self.flavor = Some(runtime);
Ok(())
}
fn set_worker_threads(
&mut self,
worker_threads: syn::Lit,
span: Span,
) -> Result<(), syn::Error> {
if self.worker_threads.is_some() {
return Err(syn::Error::new(
span,
"`worker_threads` set multiple times.",
));
}
let worker_threads = parse_int(worker_threads, span, "worker_threads")?;
if worker_threads == 0 {
return Err(syn::Error::new(span, "`worker_threads` may not be 0."));
}
self.worker_threads = Some((worker_threads, span));
Ok(())
}
fn set_start_paused(&mut self, start_paused: syn::Lit, span: Span) -> Result<(), syn::Error> {
if self.start_paused.is_some() {
return Err(syn::Error::new(span, "`start_paused` set multiple times."));
}
let start_paused = parse_bool(start_paused, span, "start_paused")?;
self.start_paused = Some((start_paused, span));
Ok(())
}
fn set_crate_name(&mut self, name: syn::Lit, span: Span) -> Result<(), syn::Error> {
if self.crate_name.is_some() {
return Err(syn::Error::new(span, "`crate` set multiple times."));View on GitHub (pinned to 0267ce9170)
Solutions
- Set worker_threads to at least 1
- Remove worker_threads to let tokio pick the number of available cores
- If the count is derived, clamp it: worker_threads = value.max(1)
Example fix
// before
#[tokio::main(flavor = "multi_thread", worker_threads = 0)]
async fn main() {}
// after
#[tokio::main(flavor = "multi_thread", worker_threads = 4)]
async fn main() {} Defensive patterns
Strategy: validation
Validate before calling
fn check_worker_threads(n: i64) -> Result<(), String> {
if n >= 1 { Ok(()) } else { Err("worker_threads must be >= 1".into()) }
} Prevention
- Never pass computed values that could be 0 as worker_threads
- Clamp derived thread counts with .max(1) in your constant definitions
- Omit worker_threads to let tokio size the pool automatically
When it happens
Trigger: #[tokio::main(flavor = "multi_thread", worker_threads = 0)] — or any expression that parses to 0 via parse_int, such as worker_threads = 0x0.
Common situations: Computing thread count from a constant that defaulted to 0; misunderstanding that worker_threads must be >= 1; template/config substitution inserting a placeholder 0.
Related errors
- No such runtime flavor `{s}`. The runtime flavors are `curre
- `worker_threads` set multiple times.
- `start_paused` set multiple times.
- `crate` set multiple times.
- `unhandled_panic` set multiple times.
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/b476d350c7072891.
Report an issue: GitHub.