dbt-labs/dbt-core · error · syn::Error

No such unhandled panic behavior `{s}`. The unhandled panic

Error message

No such unhandled panic behavior `{s}`. The unhandled panic behaviors are `ignore` and `shutdown_runtime`.

What it means

After parsing `unhandled_panic` as a string, the macro converts it to an UnhandledPanic enum via from_str; only `ignore` and `shutdown_runtime` are accepted. Any other string produces this compile error at the attribute value's span. This mirrors tokio::runtime::UnhandledPanic's FromStr.

Source

Thrown at crates/dbt-runtime-macros/src/entry.rs:191

        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.",
            ));
        }

        let unhandled_panic = parse_string(unhandled_panic, span, "unhandled_panic")?;
        let unhandled_panic =
            UnhandledPanic::from_str(&unhandled_panic).map_err(|err| syn::Error::new(span, err))?;
        self.unhandled_panic = Some((unhandled_panic, span));
        Ok(())
    }

    fn macro_name(&self) -> &'static str {
        if self.is_test {
            "dbt_runtime::test"
        } else {
            "dbt_runtime::main"
        }
    }

    fn build(&self) -> Result<FinalConfig, syn::Error> {
        use RuntimeFlavor as F;

        let flavor = self.flavor.unwrap_or(self.default_flavor);

        let worker_threads = match (flavor, self.worker_threads) {

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Use exactly `ignore` or `shutdown_runtime` as the value
  2. Fix case: values are lowercase snake_case
  3. Remove the option to use the default behavior

Example fix

// before
#[tokio::test(unhandled_panic = "abort")]
async fn t() {}

// after
#[tokio::test(unhandled_panic = "shutdown_runtime")]
async fn t() {}
Defensive patterns

Strategy: validation

Validate before calling

fn check_unhandled_panic(v: &str) -> Result<(), String> {
    match v {
        "ignore" | "shutdown_runtime" => Ok(()),
        other => Err(format!("invalid unhandled_panic `{other}`; use `ignore` or `shutdown_runtime`")),
    }
}

Prevention

When it happens

Trigger: #[tokio::test(unhandled_panic = "abort")] or any misspelling like `shutdown-runtime`, `ShutdownRuntime`, `panic` — anything UnhandledPanic::from_str rejects.

Common situations: Guessing valid behavior names; using kebab-case instead of snake_case; assuming tokio Builder's enum variant names translate directly to attribute strings.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/55d89b52deb43446. Report an issue: GitHub.