dbt-labs/dbt-core · error · syn::Error
`crate` set multiple times.
Error message
`crate` set multiple times.
What it means
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.
Source
Thrown at crates/dbt-runtime-macros/src/entry.rs:170
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."));
}
let name_path = parse_path(name, span, "crate")?;
self.crate_name = Some(name_path);
Ok(())
}
fn set_unhandled_panic(
&mut self,
unhandled_panic: syn::Lit,
span: Span,
) -> Result<(), syn::Error> {
if self.unhandled_panic.is_some() {
return Err(syn::Error::new(
span,
"`unhandled_panic` set multiple times.",
));
}
View on GitHub (pinned to 0267ce9170)
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
Example fix
// before
#[tokio::main(crate = "tokio", crate = "my_app::tokio")]
async fn main() {}
// after
#[tokio::main(crate = "my_app::tokio")]
async fn main() {} Defensive patterns
Strategy: validation
Validate before calling
fn check_crate_arg_once(attr_src: &str) -> Result<(), String> {
let n = attr_src.matches("crate =").count();
if n <= 1 { Ok(()) } else { Err("duplicate `crate` attribute arg".into()) }
} Prevention
- 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 =`
When it happens
Trigger: #[tokio::main(crate = "tokio", crate = "my_tokio")] — passing the `crate` key twice in one attribute.
Common situations: Re-export setups where a wrapper crate re-exports tokio and both the wrapper and the developer add a `crate` argument; mechanical attribute merging.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- `worker_threads` set multiple times.
- `start_paused` set multiple times.
- `unhandled_panic` set multiple times.
- No such runtime flavor `{s}`. The runtime flavors are `curre
- `worker_threads` may not be 0.
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/104e7a3670fb9212.
Report an issue: GitHub.