zeroclaw-labs/zeroclaw · error

OpenAiCompatibleBuilder: auth_style() is required

Error message

OpenAiCompatibleBuilder: auth_style() is required

What it means

OpenAiCompatibleBuilder.build() requires an auth style (how the API key is attached: e.g. Authorization bearer header vs query parameter) because there is no safe default across OpenAI-compatible endpoints. This expect() panic fires when .auth_style() was never called before .build().

Source

Thrown at crates/zeroclaw-providers/src/compatible.rs:558

    /// Finalize the builder into a ready provider. Every optional construction
    /// value must be set on this builder; the returned provider has no
    /// post-construction mutators.
    ///
    /// # Panics
    /// Panics if [`Self::display_name`], [`Self::base_url`], or
    /// [`Self::auth_style`] was not called — those three fields carry no
    /// sensible default and every real call site sets them.
    pub fn build(self) -> OpenAiCompatibleModelProvider {
        let name = self
            .name
            .expect("OpenAiCompatibleBuilder: display_name() is required");
        let base_url = self
            .base_url
            .expect("OpenAiCompatibleBuilder: base_url() is required");
        let auth_style = self
            .auth_style
            .expect("OpenAiCompatibleBuilder: auth_style() is required");
        // Either merge preset can enable the shared merge behavior.
        let merge_system_into_user =
            self.merge_system_into_user || self.merge_system_into_user_preserve_native;
        // Default `native_tool_calling` is `!merge_system_into_user_disable_native`,
        // i.e. only the "combined preset" builder setter disables it. The
        // explicit `without_native_tools()` override wins if present.
        let native_tool_calling = self
            .native_tool_calling_override
            .unwrap_or(!self.merge_system_into_user);
        // Read the PEM bytes now so later HTTP clients incur no per-request I/O.
        // A read error is logged at WARN and TLS falls back to system roots —
        // preserving the established warning-and-fallback semantics.
        let tls_ca_cert_pem =
            self.tls_ca_cert_path
                .as_deref()
                .and_then(|path| match std::fs::read(path) {
                    Ok(bytes) => Some(bytes),
                    Err(e) => {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Call .auth_style(...) matching the provider (bearer-header for most OpenAI-compatible APIs) before .build().
  2. Check how sibling provider presets in crates/zeroclaw-providers set auth_style and copy the convention.
  3. Validate the whole builder contract (display_name + base_url + auth_style) in one place before build so all missing fields are reported together.

Example fix

// before
let provider = OpenAiCompatibleModelProvider::builder()
    .display_name("my-llm")
    .base_url(url)
    .build(); // panics: auth_style() is required

// after
let provider = OpenAiCompatibleModelProvider::builder()
    .display_name("my-llm")
    .base_url(url)
    .auth_style(AuthStyle::Bearer)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

// Decide the auth style from config before building:
let auth_style = match config.auth_style.as_deref() {
    Some("bearer") => AuthStyle::Bearer,
    Some("query") => AuthStyle::QueryParam,
    other => return Err(anyhow::anyhow!("unsupported auth_style: {other:?}")),
};
let provider = OpenAiCompatibleModelProvider::builder()
    .display_name(name)
    .base_url(base_url)
    .auth_style(auth_style)
    .build();

Try / catch

let provider = std::panic::catch_unwind(|| builder.build())
    .map_err(|_| anyhow::anyhow!("provider builder contract violated: auth_style required"))?;

Prevention

When it happens

Trigger: Building an OpenAiCompatibleModelProvider via builder().build(), http_client(), streaming_http_client(), or make_model_provider() without calling .auth_style(AuthStyle::...) beforehand. Also when base_url was fixed (error 1520) but the auth-style setter was still omitted.

Common situations: Porting a provider preset that used a different auth convention; new integrations where the author set the key but not how it is transmitted; refactoring that drops the auth_style call while fixing a base_url panic.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/279e84625a86aa12. Report an issue: GitHub.