dbt-labs/dbt-core · error · syn::Error
The `start_paused` option requires the `current_thread` runt
Error message
The `start_paused` option requires the `current_thread` runtime flavor. Use `#[{macro_name}(flavor = "current_thread")]` What it means
This compile-time error comes from the dbt_runtime macro's config builder in crates/dbt-runtime-macros/src/entry.rs. It fires during `FinalConfig::build` (invoked from `build_config`) when the attribute is given `start_paused = true` while the resolved runtime flavor is `Threaded` (multi_thread). `start_paused` is a tokio testing/pausing feature that only exists on the current_thread (or Local) runtime, so the macro rejects the combination at macro-expansion time with a syn::Error pointing at the `start_paused` argument's span.
Source
Thrown at crates/dbt-runtime-macros/src/entry.rs:237
worker_threads.map(|(val, _span)| val)
}
(F::Threaded, _) => {
let msg = if self.flavor.is_none() {
"The default runtime flavor is `multi_thread`, but the `rt-multi-thread` feature is disabled."
} else {
"The runtime flavor `multi_thread` requires the `rt-multi-thread` feature."
};
return Err(syn::Error::new(Span::call_site(), msg));
}
};
let start_paused = match (flavor, self.start_paused) {
(F::Threaded, Some((_, start_paused_span))) => {
let msg = format!(
"The `start_paused` option requires the `current_thread` runtime flavor. Use `#[{}(flavor = \"current_thread\")]`",
self.macro_name(),
);
return Err(syn::Error::new(start_paused_span, msg));
}
(F::CurrentThread | F::Local, Some((start_paused, _))) => Some(start_paused),
(_, None) => None,
};
let unhandled_panic = match (flavor, self.unhandled_panic) {
(F::Threaded, Some((_, unhandled_panic_span))) => {
let msg = format!(
"The `unhandled_panic` option requires the `current_thread` runtime flavor. Use `#[{}(flavor = \"current_thread\")]`",
self.macro_name(),
);
return Err(syn::Error::new(unhandled_panic_span, msg));
}
(F::CurrentThread | F::Local, Some((unhandled_panic, _))) => Some(unhandled_panic),
(_, None) => None,
};
Ok(FinalConfig {View on GitHub (pinned to 0267ce9170)
Solutions
- Change the flavor attribute to `flavor = "current_thread"`: e.g. `#[dbt_runtime::main(flavor = "current_thread", start_paused = true)]`.
- Remove the `start_paused = true` option if you actually need the multi_thread runtime.
- If you need both worker threads and paused time, restructure: run the paused logic inside a `tokio::time::pause()`-friendly current_thread context spawned from the threaded entry, or split tests into current_thread tests.
Example fix
// before
#[dbt_runtime::test(flavor = "multi_thread", start_paused = true)]
async fn my_test() {
tokio::time::sleep(Duration::from_secs(3600)).await;
}
// after
#[dbt_runtime::test(flavor = "current_thread", start_paused = true)]
async fn my_test() {
tokio::time::sleep(Duration::from_secs(3600)).await;
} Defensive patterns
Strategy: validation
Validate before calling
// Compile-time check before using start_paused: it is only valid on current_thread/local flavors.
const FLAVOR: &str = "current_thread";
const START_PAUSED: bool = true;
const _: () = assert!(FLAVOR != "multi_thread" || !START_PAUSED, "start_paused requires flavor = \"current_thread\"");
#[dbt_runtime::test(flavor = "current_thread", start_paused = true)]
async fn t() {} Type guard
fn is_start_paused_compatible(flavor: &str) -> bool {
matches!(flavor, "current_thread" | "local")
} Prevention
- Remember the pairing rule: start_paused <-> current_thread, worker_threads <-> multi_thread.
- Never add start_paused to an entry that uses worker_threads or flavor = "multi_thread".
- Keep paused-time tests on plain #[tokio::test]-style single-threaded entries.
When it happens
Trigger: Writing `#[dbt_runtime::main(flavor = "multi_thread", start_paused = true)]` (or `#[dbt_runtime::test(...)]` with the same combo), or relying on the default flavor being multi_thread while passing only `start_paused = true`. Raised in `build` when flavor == RuntimeFlavor::Threaded and self.start_paused is Some.
Common situations: Copying a test that uses `#[tokio::test(start_paused = true)]` and adding a multi_thread flavor for heavier tests; enabling start_paused to use tokio time auto-advance while forgetting that pause requires a single-threaded runtime; migrating tokio attribute args to dbt_runtime without knowing flavor constraints.
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
- The `unhandled_panic` option requires the `current_thread` r
- No such runtime flavor `{s}`. The runtime flavors are `curre
- No such unhandled panic behavior `{s}`. The unhandled panic
- The default runtime flavor is `multi_thread`, but the `rt-mu
- The runtime flavor `multi_thread` requires the `rt-multi-thr
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/b87c81454967c9a1.
Report an issue: GitHub.