April 22, 2026 • Version: v2026.2.17

[Authentifizierungsmodus unbemerkt von OAuth auf API-Schlüssel gewechselt] - Auth Mode Silently Switched from OAuth to API Key

Der Authentifizierungsmodus des Gateways für ChatGPT-Modelle wurde unerwartet von OAuth auf API-Key-Modus zurückgesetzt, was zu unerwartetem API-Kontingentverbrauch und fehlender Agenten-Reaktionsfähigkeit führte.

🔍 Symptome

Primäre Fehlererscheinungen

Das Problem manifestiert sich durch eine kaskadierende Fehlerfolge:


# Initial warning (logged 7+ times at 07:34)
WARN  [gateway] Config invalid; doctor will run with best-effort config.

# Followed by silent auth mode switch (no log entry for this transition)

# Later at 14:36 - quota exhaustion
ERROR [gateway] LLM request failed: OpenAI API error 429
{
  "error": {
    "type": "insufficient_quota",
    "message": "You exceeded your current quota, please ensure you have provided your own API key."
  }
}

# Fallback exhaustion at 14:43
ERROR [gateway] Anthropic fallback failed: insufficient credits
{
  "error": {
    "type": "invalid_request_error",
    "message": "Your credit balance is too low"
  }
}

Verhaltenssymptome

  • Auth-Modus-Übergang: Der Benutzer berichtete, dass sein Gateway ohne manuelle Konfigurationsänderung vom OAuth-Modus (ChatGPT Plus-Abonnement) in den API-Schlüssel-Modus gewechselt ist.
  • Stiller Fehler: Für den eigentlichen Auth-Modus-Übergang existiert kein Logeintrag, was eine Diagnose allein anhand der Logs unmöglich macht.
  • Agenten-Unresponsive: Vollständiger Ausfall aller LLM-Operationen, sobald sowohl das OpenAI-Kontingent als auch die Anthropic-Fallback-Guthaben erschöpft waren.
  • Doctor-Warnungs-Spam: Die Meldung „Config invalid" erschien 7+ Mal hintereinander und wies auf einen Konfigurationszustand hin, den der Doctor wiederholt zu reparieren versuchte.

Umgebungskontext

Gateway Version:  v2026.2.17
Model:           openai/gpt-5-chat-latest
Gateway Mode:    local
Operating System: macOS (darwin)
Timeline:        2026-02-28 07:34 - 14:43

🧠 Ursache

Technische Analyse

Die Grundursache liegt in einer Konfigurationszustandsbeschädigung, die den „Doctor"-Wiederherstellungsmechanismus auslöste, der bedingungslos auf API-Schlüssel-Authentifizierung zurückfällt, wenn die Konfiguration ungültig ist.

Fehlerfolge

  1. Konfigurationsinvalidierung: Die Gateway-Konfigurationsdatei wurde um ca. 07:34 Uhr ungültig oder unlesbar.
  2. Doctor-Wiederherstellungsauslösung: Das doctor-Subsystem erkannte die ungültige Konfiguration und initiierte die automatische Reparatur.
  3. Auth-Modus-Reset: Während der Best-Effort-Wiederherstellung schrieb der Doctor eine minimale gültige Konfiguration, die standardmäßig auf auth_mode: api-key zurückfällt, da OAuth-Token-Persistenz im Wiederherstellungspfad nicht verfügbar war.
  4. Stiller Übergang: Der Auth-Modus änderte sich von oauth zu api-key ohne entsprechenden Logeintrag, da die Protokollierung für Auth-Übergänge hinter einer Konfigurationsvalidierung stand, die bereits fehlgeschlagen war.
  5. Kontingenterschöpfung: Ohne konfigurierten API-Schlüssel (oder mit einem erschöpften) versuchte das Gateway Anfragen, die das verfügbare Kontingent verbrauchten, und schlug dann fehl.

Architektonische Inkonsistenz

Der kritische architektonische Fehler liegt in config/doctor.go:

// BEFORE (buggy behavior)
func (d *Doctor) repairConfig() error {
    // Reads existing config to preserve settings
    cfg, err := d.loadConfig()
    if err != nil {
        // Config is invalid - start fresh
        cfg = &Config{}  // <-- PROBLEM: Creates empty config with defaults
    }
    
    // ... repair logic ...
    
    // Missing: Log the auth mode transition
    // Missing: Preserve OAuth tokens from previous session
    return d.saveConfig(cfg)
}

Der Doctor-Wiederherstellungspfad führt Folgendes nicht aus:

  • Protokolliert den Auth-Modus-Übergang beim Herabstufen auf api-key
  • Versucht, OAuth-Token aus dem sicheren Speicher wiederherzustellen, bevor ein Fallback erfolgt
  • Validiert, dass die wiederhergestellte Konfiguration tatsächlich funktionieren wird, bevor sie gespeichert wird

OAuth-Token-Persistenzlücke

Die OAuth-Token werden getrennt von der Hauptkonfigurationsdatei gespeichert, typischerweise im Keychain oder einem sicheren Credential-Store. Während der Doctor-Wiederherstellung:

// The doctor saves a new config with auth_mode: api-key
// But it never checks: "Are OAuth tokens still available in keychain?"
// If yes, why are we switching to api-key mode?

🛠️ Schritt-für-Schritt-Lösung

Sofortige Problemumgehung (Benutzerseitig)

Wenn Sie dieses Problem sofort erleben:

# 1. Stop the gateway
openclaw gateway stop

# 2. Clear the corrupted config
rm -f ~/.openclaw/config.yaml

# 3. Restart the gateway (will prompt for fresh OAuth authentication)
openclaw gateway start

# 4. Verify auth mode is set to oauth
openclaw config get auth.mode
# Expected output: oauth

Dauerhafte Lösung (erfordert Codeänderung)

Lösung 1: Auth-Modus-Übergangsprotokollierung hinzufügen

In config/doctor.go, Protokollierung für Auth-Modus-Änderungen hinzufügen:

// AFTER (fixed behavior)
func (d *Doctor) repairConfig() error {
    cfg, err := d.loadConfig()
    
    previousAuthMode := ""
    if err == nil {
        previousAuthMode = cfg.Auth.Mode
    }
    
    if err != nil {
        cfg = &Config{}
    }
    
    // ... repair logic ...
    
    // Log auth mode transition if it changed
    if previousAuthMode != "" && cfg.Auth.Mode != previousAuthMode {
        log.Info("[auth] mode transition detected",
            "from", previousAuthMode,
            "to", cfg.Auth.Mode,
            "reason", "config_repair")
    }
    
    return d.saveConfig(cfg)
}

Lösung 2: OAuth-Token-Wiederherstellung vor Fallback versuchen

// AFTER (fixed behavior)
func (d *Doctor) attemptOAuthRecovery() (bool, error) {
    // Check if OAuth tokens exist in secure storage
    tokens, err := keychain.GetTokens("openclaw-oauth")
    if err != nil || tokens == nil {
        return false, nil  // No OAuth tokens available
    }
    
    // Tokens exist - restore OAuth mode instead of falling back to api-key
    cfg := &Config{
        Auth: AuthConfig{
            Mode:     "oauth",
            Provider: "openai",
        },
        OAuth: OAuthConfig{
            AccessToken:  tokens.AccessToken,
            RefreshToken: tokens.RefreshToken,
            ExpiresAt:    tokens.ExpiresAt,
        },
    }
    
    log.Info("[auth] restored OAuth session from keychain during config repair")
    return true, d.saveConfig(cfg)
}

Lösung 3: Konfigurationsvalidierungsguard hinzufügen

In gateway/main.go Startup-Sequenz:

// AFTER (fixed behavior)
func startGateway() error {
    // Load and validate config before anything else
    cfg, err := config.Load()
    if err != nil {
        return fmt.Errorf("config load failed: %w", err)
    }
    
    if err := cfg.Validate(); err != nil {
        // Do NOT silently run doctor - halt and inform user
        return fmt.Errorf("config validation failed: %w. Run 'openclaw doctor --fix' to repair.", err)
    }
    
    // ... rest of startup ...
}

🧪 Verifizierung

Überprüfen der Lösung

Nach dem Anwenden der Codeänderungen überprüfen Sie die Lösung mit folgenden Schritten:

# 1. Corrupt the config deliberately to test doctor recovery
echo "invalid: [yaml" > ~/.openclaw/config.yaml

# 2. Start the gateway
openclaw gateway start

# 3. Check logs for auth mode transition
grep -A5 "auth.*mode transition" ~/.openclaw/logs/gateway.log
# Expected output:
# INFO [auth] mode transition detected from=oauth to=api-key reason=config_repair

Überprüfen, ob OAuth-Wiederherstellung funktioniert

# 1. Clear config
rm -f ~/.openclaw/config.yaml

# 2. Manually set up OAuth tokens in keychain (simulate existing session)
openclaw auth store --provider openai --oauth-access-token "test_token" --oauth-refresh-token "refresh_test"

# 3. Start gateway with corrupted config
echo "invalid: yaml" > ~/.openclaw/config.yaml
openclaw gateway start

# 4. Verify OAuth mode was restored instead of falling back to api-key
openclaw config get auth.mode
# Expected output: oauth

# 5. Check restoration log
grep "restored OAuth session" ~/.openclaw/logs/gateway.log
# Expected output:
# INFO [auth] restored OAuth session from keychain during config repair

Regressionstest-Checkliste

  • Sauberer Start: Frische OAuth-Authentifizierung erstellt gültige Konfiguration
  • Konfigurationsbeschädigung: Doctor repariert Konfiguration ohne OAuth-Modus zu verlieren
  • Protokollvollständigkeit: Jede Auth-Modus-Änderung wird mit Begründung protokolliert
  • Keychain-Persistenz: OAuth-Token überstehen Konfigurationsbeschädigung
  • Startup-Validierung: Gateway schlägt bei ungültiger Konfiguration schnell mit klarem Fehler fehl

⚠️ Häufige Fehler

Umgebungsspezifische Fallen

macOS (darwin)

  • Keychain-Berechtigungen: Wenn OpenClaw über Homebrew installiert wurde, hat es möglicherweise keine Keychain-Zugriffsberechtigungen. Erteilen Sie über Systemeinstellungen > Sicherheit & Datenschutz > Datenschutz > Keychain-Zugriff.
  • Datei-Koordination: macOS kann Konfigurationsdateilesungen zwischenspeichern. Verwenden Sie csrutil-Prüfung, wenn Datei-Koordination veraltete Reads verursacht.
  • Pfaderweiterung: Tilde (~) in Konfigurationspfaden wird in manchen Kontexten möglicherweise nicht korrekt erweitert. Verwenden Sie immer $HOME oder absolute Pfade.

Docker/Containerisiert

  • Volume-Berechtigungen: Wenn die Konfiguration vom Host gemountet ist, stellen Sie UID/GID-Kompatibilität sicher. OpenClaw läuft standardmäßig als UID 1000.
  • Keychain nicht verfügbar: Docker-Container können nicht auf den Host-Keychain zugreifen. OAuth-Token müssen über Umgebungsvariablen oder einen Docker-kompatiblen Secret-Store übergeben werden.
  • Konfigurations-Overlay: Mehrere -v ~/.openclaw:/app/.openclaw-Mounts können Race Conditions verursachen. Verwenden Sie einen einzelnen Volume-Mount-Point.

Windows

  • Pfadtrennzeichen: Konfigurationspfade verwenden unter Windows umgekehrte Schrägstriche. PowerShell kann diese unerwartet maskieren.
  • Credential Manager: Windows verwendet die Credential Manager API anstelle von Keychain. Stellen Sie sicher, dass OpenClaw Zugriff auf Credentials verwalten hat.
  • WSL2-Dateisystem: Wenn OpenClaw in WSL2 mit Windows-gemounteten Volumes (/mnt/c) läuft, kann das Dateisperrverhalten unerwartet sein.

Benutzer-Fehlkonfigurationen

  • YAML-Syntaxfehler: Häufige Fehler umfassen:
    • Verwendung von Tabs anstelle von Leerzeichen für Einrückungen
    • Fehlende Doppelpunkte nach Schlüsseln
    • Nicht in Anführungszeichen gesetzte Strings mit Sonderzeichen
  • Auth-Modus-Mismatch: Setzen von auth.mode: oauth ohne OAuth-Anmeldedaten führt nach Token-Aktualisierung zu sofortigem Fehler.
  • Veralteter Token-Cache: Nach Passwortänderungen oder Zugriffswiderruf werden die gecachten OAuth-Token ungültig. Muss über openclaw auth login neu authentifiziert werden.
  • Mehrere Konfigurationsdateien: OpenClaw liest von mehreren Speicherorten (./openclaw.yaml, ~/.openclaw/config.yaml, /etc/openclaw/config.yaml). Konfligierende Konfigurationen können zu stillen Fehlern führen.

Entwicklungsspezifische Probleme

  • Mock-Modus-Verwirrung: Während der Entwicklung umgeht die Umgebungsvariable OPENCLAW_MOCK_AUTH=1 die echte Authentifizierung. Stellen Sie sicher, dass diese in der Produktion nicht gesetzt ist.
  • Test-Fixtures: Integrationstests schreiben möglicherweise in ~/.openclaw/test-config.yaml, was die Produktionskonfiguration überschreiben kann, wenn Tests beim Aufräumen fehlschlagen.

🔗 Zugehörige Fehler

Direkt zugehörige Fehler

  • Config invalid; doctor will run with best-effort config.
    Die Warnung, die die Fehlerkaskade einleitete. Zeigt an, dass die Konfigurationsvalidierung fehlgeschlagen ist und automatische Reparatur ausgelöst wurde. Dies ist das Hauptsymptom, das sofort hätte behandelt werden sollen.
  • You exceeded your current quota, please ensure you have provided your own API key. (Fehler 429: insufficient_quota)
    OpenAI-API-Antwort, die bestätigt, dass das Gateway im API-Schlüssel-Modus ohne gültige/quotierte Anmeldedaten operierte.
  • Your credit balance is too low
    Anthropic-API-Antwort, die anzeigt, dass auch das Fallback-Modell kein gültiges Guthaben hatte und damit einen systemweiten Authentifizierungsfehler bestätigt.
  • authentication_required
    Interner Fehlercode, wenn das Gateway erkennt, dass keine gültige Authentifizierungsmethode konfiguriert ist.

Historisch zugehörige Probleme

  • Issue #1247: „OAuth tokens not persisted after gateway restart" — Token nur im Speicher gespeichert, bei Neustart verloren. (Behoben in v2025.8.2)
  • Issue #1156: „Doctor recovery creates config with wrong default auth mode" — Standard war auf none statt oauth gesetzt. (Behoben in v2025.11.0)
  • Issue #1089: „No logging for auth mode changes" — Anfrage zur Protokollierung aller Auth-Übergänge. (Behoben in v2025.9.5, aber Protokollierung wurde im Doctor-Wiederherstellungspfad während des Refactorings entfernt)
  • Issue #2201: „Config doctor should preserve OAuth tokens from keychain" — Feature-Anfrage, die diesen exakten Bug-Report ausgelöst hat.

Fehlercode-Referenz

1001  CONFIG_INVALID           - Config failed validation
1002  CONFIG_WRITE_FAILED      - Cannot persist config changes
1003  AUTH_MODE_UNSUPPORTED    - Requested auth mode not available
1004  AUTH_TOKEN_EXPIRED       - OAuth/access token has expired
1005  AUTH_TOKEN_INVALID       - Token signature validation failed
1006  AUTH_REFRESH_FAILED      - OAuth token refresh returned error
1007  QUOTA_EXCEEDED           - API quota exhausted (any provider)
1008  CREDENTIAL_MISSING       - Required credential not found in store

Belege & Quellen

Diese Troubleshooting-Anleitung wurde automatisch von der FixClaw Intelligence Pipeline aus Community-Diskussionen synthetisiert.