zeroclaw-labs/zeroclaw · error

microsoft365.auth_flow must be 'client_credentials' or 'devi

Error message

microsoft365.auth_flow must be 'client_credentials' or 'device_code'

What it means

microsoft365.auth_flow is trimmed and must equal exactly "client_credentials" or "device_code"; anything else bails from the first M365 validation block with this quoted-variant message. Comparison is case-sensitive with no normalization beyond trimming, so "Client_Credentials" or "DeviceCode" fail. These are the only two flows the integration implements — authorization_code and interactive flows are not supported.

Source

Thrown at crates/zeroclaw-config/src/schema.rs:21710

            if tenant.is_none() {
                anyhow::bail!(
                    "microsoft365.tenant_id must not be empty when microsoft365 is enabled"
                );
            }
            let client = self
                .microsoft365
                .client_id
                .as_deref()
                .map(str::trim)
                .filter(|s| !s.is_empty());
            if client.is_none() {
                anyhow::bail!(
                    "microsoft365.client_id must not be empty when microsoft365 is enabled"
                );
            }
            let flow = self.microsoft365.auth_flow.trim();
            if flow != "client_credentials" && flow != "device_code" {
                anyhow::bail!(
                    "microsoft365.auth_flow must be 'client_credentials' or 'device_code'"
                );
            }
            if flow == "client_credentials"
                && self
                    .microsoft365
                    .client_secret
                    .as_deref()
                    .is_none_or(|s| s.trim().is_empty())
            {
                anyhow::bail!(
                    "microsoft365.client_secret must not be empty when auth_flow is 'client_credentials'"
                );
            }
        }

        // Microsoft 365
        if self.microsoft365.enabled {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Use `auth_flow = "client_credentials"` for daemon/service auth (note: client_secret then becomes mandatory)
  2. Use `auth_flow = "device_code"` for interactive sign-in without a secret
  3. Spell it exactly lowercase with the underscore — trim handles surrounding spaces, not casing

Example fix

# before
[microsoft365]
auth_flow = "authorization_code"

# after
[microsoft365]
auth_flow = "client_credentials"
Defensive patterns

Strategy: validation

Validate before calling

fn m365_flow_precheck(m: &zeroclaw_config::Microsoft365Config) -> Result<(), String> {
    if !m.enabled { return Ok(()); }
    let flow = m.auth_flow.trim();
    if flow != "client_credentials" && flow != "device_code" {
        return Err(format!("unsupported auth_flow: {flow:?}"));
    }
    Ok(())
}

Type guard

fn is_supported_m365_flow(flow: &str) -> bool {
    matches!(flow.trim(), "client_credentials" | "device_code")
}

Try / catch

if let Err(err) = config.validate() {
    if err.to_string().contains("microsoft365.auth_flow") {
        // set auth_flow to exactly client_credentials or device_code (lowercase)
    }
}

Prevention

When it happens

Trigger: Set auth_flow to "authorization_code", "interactive", "Client_Credentials" (wrong case), or any other string; the trimmed value must byte-match one of the two allowed names.

Common situations: Copying auth flow names from generic Azure OAuth samples; assuming a wider flow set than implemented; casing drift from documentation rewrites.

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 zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/d47ee89c4f7b0724. Report an issue: GitHub.