dbt-labs/dbt-core · info

test tracing subscriber should be valid

Error message

test tracing subscriber should be valid

What it means

A test-only `.expect()` asserting that a tracing subscriber built from test layers is valid. In the dbt_project_config test helper, a subscriber is registered via `set_default`-style setup, and an invalid layer configuration (e.g. duplicate/dropped subscriber) causes this panic before the actual config assertions run.

Source

Thrown at crates/dbt-parser/src/dbt_project_config.rs:1340

        T: ResolvableConfig<T> + PartialEq,
        S: TypedRecursiveConfig + Into<T> + for<'de> serde::Deserialize<'de>,
        T::PackageDefaults: Default,
    {
        // Diagnostics are emitted through the tracing layer, so capture them with a
        // test consumer rather than a status reporter.
        let (test_layer, _, _, log_records) = TestLayer::new();
        let subscriber = create_tracing_subcriber_with_layer(
            tracing::level_filters::LevelFilter::TRACE,
            test_data_layer(
                1,
                None,
                false,
                std::iter::empty(),
                std::iter::once(Box::new(test_layer) as ConsumerLayer),
            ),
            &[],
        )
        .expect("test tracing subscriber should be valid");

        let configs: S = dbt_jinja_utils::serde::from_yaml_raw(yaml, None, false, None)
            .expect("yaml deserializes into config type");

        // The data layer only records events emitted within an active span, so run
        // `init_project_config` inside a root span.
        let result = tracing::subscriber::with_default(subscriber, || {
            let _root = create_root_info_span(MockDynSpanEvent {
                name: "root".to_string(),
                flags: TelemetryOutputFlags::ALL,
                ..Default::default()
            })
            .entered();

            init_project_config::<T, S>(
                &Some(configs),
                Default::default(),
                None,

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Ensure no other global default tracing subscriber is installed before these tests run
  2. Use `try_set_default`/scoped `with_default` instead of a global set in test setups
  3. Fix the layer/filter configuration passed to the subscriber builder
  4. Run the test in isolation (`cargo test -p dbt-parser <test_name>`) to rule out subscriber conflicts

Example fix

// before
tracing::subscriber::set_global_default(subscriber).expect("test tracing subscriber should be valid");

// after
tracing::subscriber::set_default(subscriber); // scoped, no global conflict
Defensive patterns

Strategy: try-catch

Try / catch

if tracing::subscriber::set_default(subscriber).is_none() {
    eprintln!("skipping: another subscriber holds the default");
    return;
}

Prevention

When it happens

Trigger: Running the project-config tests where `tracing::subscriber` setup rejects the composed subscriber (invalid filter or layer combination), or running tests in parallel when a global default subscriber is already installed.

Common situations: Developers running `cargo test -p dbt-parser` with test harnesses that install their own global tracing subscriber, causing conflicts; adding a layer with an invalid filter to the test telemetry setup.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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