{"record":{"id":"3dc226630172af1a","repo":"affaan-m/ECC","slug":"cannot-rebase-active-session-while-it-is","errorCode":null,"errorMessage":"Cannot rebase active session {} while it is {}","messagePattern":"Cannot rebase active session (.+?) while it is (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/session/manager.rs","lineNumber":1817,"sourceCode":"    }\n\n    Ok(WorktreeMergeOutcome {\n        session_id: session.id,\n        branch: outcome.branch,\n        base_branch: outcome.base_branch,\n        already_up_to_date: outcome.already_up_to_date,\n        cleaned_worktree: cleanup_worktree,\n    })\n}\n\npub async fn rebase_session_worktree(db: &StateStore, id: &str) -> Result<WorktreeRebaseOutcome> {\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 rebase 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::rebase_onto_base(&worktree)?;\n\n    Ok(WorktreeRebaseOutcome {\n        session_id: session.id,\n        branch: outcome.branch,\n        base_branch: outcome.base_branch,\n        already_up_to_date: outcome.already_up_to_date,\n    })","sourceCodeStart":1799,"sourceCodeEnd":1835,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/session/manager.rs#L1799-L1835","documentation":"The rebase_session_worktree function refuses to rebase a session whose state is still active (Pending, Running, Idle, or Stale). Rebasing rewrites the worktree branch history, which would corrupt any in-flight agent work. The session must reach a terminal state before rebasing is safe.","triggerScenarios":"Calling rebase_session_worktree(db, id) for a session in SessionState::Pending, Running, Idle, or Stale.","commonSituations":"User triggers a rebase to pull in latest base-branch changes while the session is still running. Stale sessions are still blocked because the agent process may still be alive.","solutions":["Stop or complete the session before calling rebase_session_worktree","Check session state is terminal before attempting rebase","For stale sessions, resolve them to a terminal state first (fail or cancel)","Schedule rebases for after session completion rather than during"],"exampleFix":"// before\nrebase_session_worktree(db, &id).await?;\n\n// after\nlet session = resolve_session(db, &id)?;\nif matches!(session.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale) {\n    return Err(anyhow!(\"Stop session {} before rebasing (current state: {})\", id, session.state));\n}\nrebase_session_worktree(db, &id).await?;","handlingStrategy":"type-guard","validationCode":"let session = resolve_session(db, id)?;\nif matches!(session.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale) {\n    return Err(anyhow!(\"Stop session {} (state: {}) before rebasing\", id, session.state));\n}","typeGuard":"fn is_rebaseable(session: &Session) -> bool {\n    !matches!(\n        session.state,\n        SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale\n    )\n}","tryCatchPattern":null,"preventionTips":["Only expose rebase actions for terminal-state sessions","Call stop_session before rebase in automated workflows","Schedule rebases as a post-completion step rather than during session execution"],"tags":["sessions","worktree","rebase","lifecycle","state-machine"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}