affaan-m/ECC · error · anyhow::Error

Cannot delete active session

Error message

Cannot delete active session {} while it is {}

What it means

The delete operation refuses to delete a session that is active (Pending, Running, or Idle). Deleting an active session would destroy its state/pid records and potentially its worktree while a process may still be using them. Note that unlike merge/rebase, Stale sessions are still deletable here.

Solutions

  1. Stop/cancel the running session first, wait for terminal state, then delete
  2. If the runner is dead, reset or finalize the session state (e.g., mark Failed) and then delete
  3. Skip deletion of active sessions in cleanup scripts and retry later
  4. Check resolve_session(db, id).state before calling delete

Example fix

// before
delete_session(db, id)?;
// after
let session = resolve_session(db, id)?;
if matches!(session.state, SessionState::Pending | SessionState::Running | SessionState::Idle) {
    eprintln!("session {} is active ({:?}); not deleting", id, session.state);
} else {
    delete_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) {
    return Err(format!("session {} not deletable in state {:?}", id, session.state));
}

Type guard

fn is_deletable(s: &Session) -> bool { !matches!(s.state, SessionState::Pending | SessionState::Running | SessionState::Idle) }

Try / catch

match delete_session(db, id) {
    Err(e) if e.to_string().starts_with("Cannot delete active session") => { /* stop session then retry */ }
    other => other,
}

Prevention

When it happens

Trigger: Calling the delete-session API (manager.rs:2314) on a session whose state matches Pending | Running | Idle.

Common situations: User deleting a session from the UI while its agent is running; cleanup scripts deleting queued sessions; trying to purge a session that is Idle but hasn't been finalized; a runner crashed leaving the session Idle and blocking deletion.

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


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/de97b9cfd61fc0ac. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/session/manager.rs:2314

            dirty.push(entry.session_id.clone());
        } else if entry.worktree_health == worktree::WorktreeHealth::Conflicted {
            conflicted.push(entry.session_id.clone());
        } else {
            queue_blocked.push(entry.session_id.clone());
        }
    }

    (active, conflicted, dirty, queue_blocked)
}

pub async fn delete_session(db: &StateStore, id: &str) -> Result<()> {
    let session = resolve_session(db, id)?;

    if matches!(
        session.state,
        SessionState::Pending | SessionState::Running | SessionState::Idle
    ) {
        anyhow::bail!(
            "Cannot delete active session {} while it is {}",
            session.id,
            session.state
        );
    }

    if let Some(worktree) = session.worktree.as_ref() {
        let _ = crate::worktree::remove(worktree);
    }

    db.delete_session(&session.id)?;
    Ok(())
}

fn agent_program(cfg: &Config, agent_type: &str) -> Result<PathBuf> {
    let harness = HarnessKind::from_agent_type(agent_type);
    let runner_key = SessionHarnessInfo::runner_key(agent_type);
    if let Some(runner) = cfg.harness_runner(&runner_key) {

View on GitHub (pinned to 8321021c54)