zeroclaw-labs/zeroclaw · error

invalid token_validation mode

Error message

invalid token_validation mode '{other}': expected 'local' or 'remote'

What it means

TokenValidationMode::from_str_config received a string that is neither 'local' nor 'remote' (comparison is case-insensitive but not trim-tolerant). This value decides whether Nevis tokens are validated locally against a JWKS endpoint or remotely via introspection, so an unknown mode fails fast at provider construction.

Solutions

  1. Set the value to exactly 'local' or 'remote' (any case, no surrounding whitespace).
  2. If remote introspection is wanted, use 'remote'; for local JWKS validation use 'local' and also set jwks_url.
  3. Validate the value at config load with a lint/schema check before the provider is constructed.
  4. Watch for whitespace: trim env-sourced values before passing them in.

Example fix

# before
token_validation = "introspection"

# after
token_validation = "remote"   # or "local" with a jwks_url set
Defensive patterns

Strategy: validation

Validate before calling

let mode = token_validation.trim().to_ascii_lowercase();
if !matches!(mode.as_str(), "local" | "remote") {
    anyhow::bail!("token_validation must be 'local' or 'remote', got '{token_validation}'");
}

Type guard

fn is_valid_token_validation_mode(s: &str) -> bool {
    matches!(s.trim().to_ascii_lowercase().as_str(), "local" | "remote")
}

Try / catch

Err(e) if e.to_string().starts_with("invalid token_validation mode") => {
    // surface to the operator with the allowed values; fail deployment, don't guess a default
}

Prevention

When it happens

Trigger: Setting token_validation = "introspection", "jwt", "JWKS", "remot" (typo), or " local" with a leading space; values passed from env vars or templated config without normalization.

Common situations: Config copied from another auth system with different mode names; YAML values quoted with stray whitespace; version migrations renaming the option; uppercase values work ('Local') but padded ones do not.

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/0427b8ea5c85f988. Report an issue: GitHub.

Appendix: source

Thrown at crates/zeroclaw-runtime/src/security/nevis.rs:36

    /// When this session expires (seconds since UNIX epoch).
    pub session_expiry: u64,
}

/// Token validation strategy.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenValidationMode {
    /// Validate JWT locally using cached JWKS keys.
    Local,
    /// Validate token by calling the Nevis introspection endpoint.
    Remote,
}

impl TokenValidationMode {
    pub fn from_str_config(s: &str) -> Result<Self> {
        match s.to_ascii_lowercase().as_str() {
            "local" => Ok(Self::Local),
            "remote" => Ok(Self::Remote),
            other => bail!("invalid token_validation mode '{other}': expected 'local' or 'remote'"),
        }
    }
}

/// Authentication model_provider backed by a Nevis instance.
/// Validates tokens, manages sessions, and resolves identities. The model_provider
/// is designed to be shared across concurrent requests (`Send + Sync`).
pub struct NevisAuthProvider {
    /// Base URL of the Nevis instance (e.g. `https://nevis.example.com`).
    instance_url: String,
    /// Nevis realm to authenticate against.
    realm: String,
    /// OAuth2 client ID registered in Nevis.
    client_id: String,
    /// OAuth2 client secret (decrypted at startup).
    client_secret: Option<String>,
    /// Token validation strategy.
    validation_mode: TokenValidationMode,

View on GitHub (pinned to 88bb9c8533)