diff --git a/scripts/claude-bridge.js b/scripts/claude-bridge.js index cefdb13..7233556 100644 --- a/scripts/claude-bridge.js +++ b/scripts/claude-bridge.js @@ -481,18 +481,26 @@ async function sendMessage(message, requestId, model = null, contextOverride = n }); } - // Hilfsfunktion: Iteration mit Fallback bei ungueltiger Session-ID + // Hilfsfunktion: Iteration mit Fallback bei ungueltiger Session-ID. + // Typischer Auslöser: "No conversation found with session ID: " + // passiert wenn die in SQLite gespeicherte Claude-Session lokal fehlt + // (neue Maschine, Projekt-Cache geloescht, frische Installation, ...). async function* iterateWithRetry() { try { for await (const ev of conversation) yield ev; } catch (err) { - // Wenn Resume-Session ungueltig → Retry ohne sessionId - if (queryOptions.sessionId) { + const msg = err?.message || String(err); + const isStaleSession = /no conversation found with session id/i.test(msg); + if (queryOptions.resume && isStaleSession) { + const staleId = queryOptions.resume; + // Rust-Seite informieren, damit die stale ID aus der DB geloescht + // wird — sonst probieren wir beim naechsten Start wieder dasselbe. + sendEvent('session-reset', { staleSessionId: staleId, reason: msg }); sendMonitorEvent('agent', 'Resume fehlgeschlagen, starte neue Session', { - reason: err.message || String(err), - oldSessionId: queryOptions.sessionId, + reason: msg, + oldSessionId: staleId, }); - delete queryOptions.sessionId; + delete queryOptions.resume; conversation = query({ prompt: fullPrompt, options: queryOptions }); for await (const ev of conversation) yield ev; } else { diff --git a/src-tauri/src/claude.rs b/src-tauri/src/claude.rs index bdd8a96..44d5df4 100644 --- a/src-tauri/src/claude.rs +++ b/src-tauri/src/claude.rs @@ -256,6 +256,25 @@ fn handle_bridge_message(app: &AppHandle, msg: BridgeMessage) { } let _ = app.emit("claude-result", &payload); } + "session-reset" => { + // Bridge meldet: resume-Session war ungueltig ("No conversation + // found with session ID"). Stale claude_session_id aus DB + // entfernen, sonst laeuft die App beim naechsten Start wieder + // in denselben Fehler. + if let Some(db_state) = app.try_state::>>() { + let db_lock = db_state.lock().unwrap(); + if let Ok(Some(active_id)) = db_lock.get_setting("active_session_id") { + if !active_id.is_empty() { + if let Ok(Some(mut session)) = db_lock.get_session(&active_id) { + let old = session.claude_session_id.take(); + let _ = db_lock.update_session(&session); + println!("🧹 Stale claude_session_id geloescht: {:?}", old); + } + } + } + } + let _ = app.emit("session-reset", &payload); + } "all-stopped" => { println!("⏹️ Alle Agents gestoppt"); let _ = app.emit("all-stopped", ());