[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
- Konfigurationsinvalidierung: Die Gateway-Konfigurationsdatei wurde um ca. 07:34 Uhr ungültig oder unlesbar.
- Doctor-Wiederherstellungsauslösung: Das
doctor-Subsystem erkannte die ungültige Konfiguration und initiierte die automatische Reparatur. - Auth-Modus-Reset: Während der Best-Effort-Wiederherstellung schrieb der Doctor eine minimale gültige Konfiguration, die standardmäßig auf
auth_mode: api-keyzurückfällt, da OAuth-Token-Persistenz im Wiederherstellungspfad nicht verfügbar war. - Stiller Übergang: Der Auth-Modus änderte sich von
oauthzuapi-keyohne entsprechenden Logeintrag, da die Protokollierung für Auth-Übergänge hinter einer Konfigurationsvalidierung stand, die bereits fehlgeschlagen war. - 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$HOMEoder 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 verwaltenhat. - 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: oauthohne 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 loginneu 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=1die 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
nonestattoauthgesetzt. (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