{"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/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/session/manager.rs#L1498-L1534","documentation":"resume_session_with_program refuses to resume a session whose state is Completed. Completed sessions represent finished work; resuming them is unsupported because their program has already terminated successfully. The caller (resume_session) surfaces this as an error to the user.","triggerScenarios":"Calling resume_session(id) or tests like resume_session_requeues_failed_session against a session whose stored state in the StateStore equals SessionState::Completed.","commonSituations":"User clicks 'resume' on a session in the UI that already finished; automation re-submitting a session id after it completed; stale client state showing the session as Failed or Pending when the DB says Completed.","solutions":["Check session.state before resuming and skip or create a new session if Completed","Start a new session instead of resuming the completed one","Refresh session state from the DB before offering the resume action in UIs/automation"],"exampleFix":"// before\nresume_session(db, id)?;\n// after\nlet session = resolve_session(db, id)?;\nif session.state == SessionState::Completed {\n    let new_id = create_session(db, &session.config)?;\n} else {\n    resume_session(db, id)?;\n}","handlingStrategy":"validation","validationCode":"let session = resolve_session(db, id)?;\nif session.state == SessionState::Completed {\n    return Err(format!(\"session {} already completed; create a new session instead\", id));\n}","typeGuard":"fn is_resumable(s: &Session) -> bool { s.state != SessionState::Completed && s.state != SessionState::Running }","tryCatchPattern":"match resume_session(db, id) {\n    Err(e) if e.to_string().contains(\"Completed sessions cannot be resumed\") => start_new_session(db, &config),\n    other => other,\n}","preventionTips":["Refresh session state from the DB before showing resume actions","Disable resume UI for Completed sessions","Treat Completed as terminal in automation; create new sessions instead"],"tags":["session","state-machine","resume"],"backgroundTag":"invalid-state-transition","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}