{"record":{"id":"ca8fcb1e9bc518d8","repo":"affaan-m/ECC","slug":"completed-sessions-cannot-be-resumed","errorCode":null,"errorMessage":"Completed sessions cannot be resumed: {}","messagePattern":"Completed sessions cannot be resumed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/session/manager.rs","lineNumber":1516,"sourceCode":"        .ok_or_else(|| anyhow::anyhow!(\"Session not found: {session_id}\"))?;\n\n    ToolLogger::new(db).query(&session.id, page, page_size)\n}\n\npub async fn resume_session(db: &StateStore, cfg: &Config, id: &str) -> Result<String> {\n    resume_session_with_program(db, cfg, id, None).await\n}\n\nasync fn resume_session_with_program(\n    db: &StateStore,\n    _cfg: &Config,\n    id: &str,\n    runner_executable_override: Option<&Path>,\n) -> Result<String> {\n    let session = resolve_session(db, id)?;\n\n    if session.state == SessionState::Completed {\n        anyhow::bail!(\"Completed sessions cannot be resumed: {}\", session.id);\n    }\n\n    if session.state == SessionState::Running {\n        anyhow::bail!(\"Session is already running: {}\", session.id);\n    }\n\n    db.update_state_and_pid(&session.id, &SessionState::Pending, None)?;\n    if let Some(worktree) = session.worktree.as_ref() {\n        if let Err(error) = worktree::sync_shared_dependency_dirs(worktree) {\n            tracing::warn!(\n                \"Shared dependency cache sync warning for resumed session {}: {error}\",\n                session.id\n            );\n        }\n    }\n    let runner_executable = match runner_executable_override {\n        Some(program) => program.to_path_buf(),\n        None => std::env::current_exe().context(\"Failed to resolve ECC executable path\")?,","sourceCodeStart":1498,"sourceCodeEnd":1534,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/session/manager.rs#L1498-L1534","documentation":"The resume_session_with_program function guards against resuming a session whose state is Completed. A completed session has finished its lifecycle and cannot be resumed — its worktree may have been merged, its process has exited, and its state is final. The check fires before any state mutation or process spawning.","triggerScenarios":"Calling resume_session(db, cfg, id) or resume_session_with_program(...) for a session whose state is SessionState::Completed.","commonSituations":"Trying to resume a session that finished normally. Replaying a session ID from logs after it already completed. UI 'resume' button that does not check terminal state first.","solutions":["Create a new session instead of resuming a completed one","Check session.state == SessionState::Completed before calling resume and show a user-facing message","If you need to re-run the same task, clone the session configuration into a new session","Track terminal state in the caller so resume is only offered for non-terminal sessions"],"exampleFix":"// before\nresume_session(db, cfg, &id).await?;\n\n// after\nlet session = resolve_session(db, &id)?;\nif session.state == SessionState::Completed {\n    return Err(anyhow!(\"Session {} is completed; create a new session to re-run\", id));\n}\nresume_session(db, cfg, &id).await?;","handlingStrategy":"type-guard","validationCode":"let session = resolve_session(db, id)?;\nif session.state == SessionState::Completed {\n    return Err(anyhow!(\"Session {} is already completed. Create a new session to re-run.\", id));\n}","typeGuard":"fn is_resumable(session: &Session) -> bool {\n    !matches!(session.state, SessionState::Completed | SessionState::Running)\n}","tryCatchPattern":null,"preventionTips":["Disable resume buttons in UIs for sessions in terminal states","Store terminal-session IDs in a separate list so they are not offered for resume","Create a new session with the same task instead of trying to resume a completed one"],"tags":["sessions","lifecycle","resume","state-machine"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}