{"record":{"id":"9102631c77e66c13","repo":"affaan-m/ECC","slug":"cannot-merge-active-session-while-it-is","errorCode":null,"errorMessage":"Cannot merge active session {} while it is {}","messagePattern":"Cannot merge active session (.+?) while it is (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/session/manager.rs","lineNumber":1783,"sourceCode":"pub struct WorktreeRebaseOutcome {\n    pub session_id: String,\n    pub branch: String,\n    pub base_branch: String,\n    pub already_up_to_date: bool,\n}\n\npub async fn merge_session_worktree(\n    db: &StateStore,\n    id: &str,\n    cleanup_worktree: bool,\n) -> Result<WorktreeMergeOutcome> {\n    let session = resolve_session(db, id)?;\n\n    if matches!(\n        session.state,\n        SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale\n    ) {\n        anyhow::bail!(\n            \"Cannot merge active session {} while it is {}\",\n            session.id,\n            session.state\n        );\n    }\n\n    let worktree = session\n        .worktree\n        .clone()\n        .ok_or_else(|| anyhow::anyhow!(\"Session {} has no attached worktree\", session.id))?;\n    let outcome = crate::worktree::merge_into_base(&worktree)?;\n\n    if cleanup_worktree {\n        crate::worktree::remove(&worktree)?;\n        db.clear_worktree(&session.id)?;\n    }\n\n    Ok(WorktreeMergeOutcome {","sourceCodeStart":1765,"sourceCodeEnd":1801,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/session/manager.rs#L1765-L1801","documentation":"The merge operation refuses to merge a session that is still active (Pending, Running, Idle, or Stale). Merging an active session's worktree could race with a live process writing to it, producing corrupt merges. Only sessions in a terminal state may be merged.","triggerScenarios":"Calling the merge-session API (manager.rs:1783) on a session whose state matches Pending | Running | Idle | Stale.","commonSituations":"Trying to merge while the agent process is still executing; a crashed session left in Idle/Stale state; a queued (Pending) session someone attempted to merge prematurely; UI showing a stale state where the session appears finished but is Stale.","solutions":["Wait for the session to reach a terminal state (Completed/Failed) before merging","Cancel or stop the running session first, then merge","Clean up Stale sessions (reap dead pids and finalize state) so they become mergeable","Verify session state via resolve_session before invoking merge"],"exampleFix":"// before\nmerge_session(db, id)?;\n// after\nlet session = resolve_session(db, id)?;\nif matches!(session.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale) {\n    eprintln!(\"session {} still active ({:?}); waiting\", id, session.state);\n} else {\n    merge_session(db, id)?;\n}","handlingStrategy":"validation","validationCode":"let session = resolve_session(db, id)?;\nif matches!(session.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale) {\n    return Err(format!(\"session {} not mergeable in state {:?}\", id, session.state));\n}","typeGuard":"fn is_mergeable(s: &Session) -> bool { !matches!(s.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale) }","tryCatchPattern":"match merge_session(db, id) {\n    Err(e) if e.to_string().starts_with(\"Cannot merge active session\") => retry_after_completion(id),\n    other => other,\n}","preventionTips":["Only trigger merge from Completed/Failed sessions","Reap Stale sessions regularly so they reach a terminal state","Gate merge automation on session-state webhooks"],"tags":["session","git-merge","state-machine"],"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"}