affaan-m/ECC · error · anyhow::Error
Cannot merge active session
Error message
Cannot merge active session {} while it is {} What it means
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.
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
Example fix
// before
merge_session(db, id)?;
// after
let session = resolve_session(db, id)?;
if matches!(session.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale) {
eprintln!("session {} still active ({:?}); waiting", id, session.state);
} else {
merge_session(db, id)?;
} Defensive patterns
Strategy: validation
Validate before calling
let session = resolve_session(db, id)?;
if matches!(session.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale) {
return Err(format!("session {} not mergeable in state {:?}", id, session.state));
} Type guard
fn is_mergeable(s: &Session) -> bool { !matches!(s.state, SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale) } Try / catch
match merge_session(db, id) {
Err(e) if e.to_string().starts_with("Cannot merge active session") => retry_after_completion(id),
other => other,
} Prevention
- Only trigger merge from Completed/Failed sessions
- Reap Stale sessions regularly so they reach a terminal state
- Gate merge automation on session-state webhooks
When it happens
Trigger: Calling the merge-session API (manager.rs:1783) on a session whose state matches Pending | Running | Idle | Stale.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot delete active session
- Cannot rebase active session
- Completed sessions cannot be resumed
- Session is already running
- an active harness configuration already exists
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/9102631c77e66c13.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/session/manager.rs:1783
pub struct WorktreeRebaseOutcome {
pub session_id: String,
pub branch: String,
pub base_branch: String,
pub already_up_to_date: bool,
}
pub async fn merge_session_worktree(
db: &StateStore,
id: &str,
cleanup_worktree: bool,
) -> Result<WorktreeMergeOutcome> {
let session = resolve_session(db, id)?;
if matches!(
session.state,
SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale
) {
anyhow::bail!(
"Cannot merge active session {} while it is {}",
session.id,
session.state
);
}
let worktree = session
.worktree
.clone()
.ok_or_else(|| anyhow::anyhow!("Session {} has no attached worktree", session.id))?;
let outcome = crate::worktree::merge_into_base(&worktree)?;
if cleanup_worktree {
crate::worktree::remove(&worktree)?;
db.clear_worktree(&session.id)?;
}
Ok(WorktreeMergeOutcome {View on GitHub (pinned to 8321021c54)