dbt-labs/dbt-core · error

`http_status_as_error` is not enabled.

Error message

`http_status_as_error` is not enabled.

What it means

vortex-client's HTTP retry hook asserts that status-code errors never reach on_error. The client is built with http_status_as_error disabled, so ureq delivers non-2xx statuses via on_response instead; a StatusCode error arriving here means the client was misconfigured. It is an internal invariant panic, not a network failure report.

Source

Thrown at crates/vortex-client/src/client.rs:244

        let mut message_batch = VortexMessageBatch {
            request_id: uuid::Uuid::new_v4().to_string(),
            payload: Vec::new(),
        };
        // Consume these messages into a batch's payload and then swap them back to
        // the original messages vector to enable retries from the caller if needed.
        std::mem::swap(&mut self.messages, &mut message_batch.payload);
        let body = message_batch.encode_to_vec();
        std::mem::swap(&mut self.messages, &mut message_batch.payload);
        body
    }

    fn on_error(&mut self, error: ureq::Error) {
        #[allow(clippy::single_match)]
        match error {
            ureq::Error::StatusCode(_) => {
                // Status codes should be handled in `on_response`
                // because `http_status_as_error` is not enabled.
                unreachable!("`http_status_as_error` is not enabled.")
            }
            _ => (),
        }
        self.last_error = Some(error);
        self.backoff();
    }

    fn on_response(&mut self, status: http::StatusCode, text: String) {
        if status.is_success() {
            self.clear_after_success();
            trace!("Successfully sent telemetry batch.");
        } else {
            self.backoff();
            trace!("Failed to send batch of messages: {status}: {text}");
            self.last_error = Some(ureq::Error::StatusCode(status.as_u16()));
        }
    }
}

View on GitHub (pinned to 0267ce9170)

Solutions

  1. Do not enable http_status_as_error on the vortex client's ureq agent
  2. Handle HTTP status codes in on_response, which is the designed path
  3. If using a custom agent, keep its error behavior matching the client's assumptions
  4. Report a bug if the panic occurs with default client settings

Example fix

// before
AgentBuilder::new().http_status_as_error(true)...
// after
AgentBuilder::new().http_status_as_error(false)... // handle statuses in on_response
Defensive patterns

Strategy: validation

Validate before calling

// before building the client, confirm the setting
let agent = ureq::AgentBuilder::new()
    .http_status_as_error(false)
    .build();

Try / catch

// statuses are expected in on_response, not on_error:
fn on_response(&mut self, resp: http::Response<&[u8]>) -> Result<(), ureq::Error> {
    if !resp.status().is_success() {
        self.last_error = Some(ureq::Error::StatusCode(resp.status().as_u16()));
        self.backoff();
    }
    Ok(())
}

Prevention

When it happens

Trigger: Calling request paths with a client configured with http_status_as_error = true (or a ureq agent constructed without the expected setting), so ureq::Error::StatusCode flows into on_error.

Common situations: Enabling http_status_as_error in client configuration; swapping the underlying ureq agent for a custom one with different error policies; upgrading ureq and changing error semantics.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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