zeroclaw-labs/zeroclaw · error · anyhow::Error

Unsupported auth profile kind: {other}

Error message

Unsupported auth profile kind: {other}

What it means

`parse_profile_kind` maps each persisted profile's `kind` string to `AuthProfileKind`; only `"oauth"` and `"token"` (exact lowercase) are valid. Any other value aborts the entire `load_locked` pass, so a single malformed profile makes the whole store unreadable — the error names the offending kind string.

Source

Thrown at crates/zeroclaw-providers/src/auth/profiles.rs:642

    #[serde(default = "default_now_rfc3339")]
    updated_at: String,
    #[serde(default)]
    metadata: BTreeMap<String, String>,
}

fn default_schema_version() -> u32 {
    CURRENT_SCHEMA_VERSION
}

fn default_now_rfc3339() -> String {
    Utc::now().to_rfc3339()
}

fn parse_profile_kind(value: &str) -> Result<AuthProfileKind> {
    match value {
        "oauth" => Ok(AuthProfileKind::OAuth),
        "token" => Ok(AuthProfileKind::Token),
        other => anyhow::bail!("Unsupported auth profile kind: {other}"),
    }
}

fn profile_kind_to_string(kind: AuthProfileKind) -> &'static str {
    match kind {
        AuthProfileKind::OAuth => "oauth",
        AuthProfileKind::Token => "token",
    }
}

fn parse_optional_datetime(value: Option<&str>) -> Result<Option<DateTime<Utc>>> {
    value.map(parse_datetime).transpose()
}

fn parse_datetime(value: &str) -> Result<DateTime<Utc>> {
    DateTime::parse_from_rfc3339(value)
        .map(|dt| dt.with_timezone(&Utc))
        .with_context(|| format!("Invalid RFC3339 timestamp: {value}"))

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set the profile's `kind` to exactly `"oauth"` or `"token"` in auth-profiles.json
  2. Remove the malformed profile entry if it is not needed
  3. Create profiles through `AuthProfile::new_oauth`/`new_token` plus `upsert_profile` instead of editing the file
  4. If the kind came from a newer version, upgrade the binary rather than editing data

Example fix

// before (auth-profiles.json)
"kind": "API-Key"

// after
"kind": "token"
Defensive patterns

Strategy: validation

Validate before calling

let raw = tokio::fs::read_to_string(store.path()).await?;
let v: serde_json::Value = serde_json::from_str(&raw)?;
let kinds_ok = v["profiles"].as_object().map_or(true, |m| {
    m.values().all(|p| matches!(p["kind"].as_str(), Some("oauth") | Some("token")))
});
if !kinds_ok { /* fix or strip the offending entry before store operations */ }

Try / catch

match store.load().await {
    Ok(d) => d,
    Err(e) if e.to_string().contains("Unsupported auth profile kind") => {
        return Err(anyhow!("edit {} : kind must be \"oauth\" or \"token\"", store.path().display()));
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: A hand-edited auth-profiles.json containing kind `"API-Key"`, `"OAuth"` (wrong case), `""`, or a future kind; a store written by a newer version that introduced kinds this binary does not know.

Common situations: Manual edits to the state file; external tooling writing its own profile entries into auth-profiles.json; version skew after downgrade.

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