ruvnet/ruflo · error · Error
Can only pause active or busy agent
Error message
Can only pause active or busy agent
What it means
Agent.pause() only accepts the 'active' and 'busy' states. This error means the agent was in some other state — idle, paused (double pause), error, or terminated — when pause() was called. It is the entity guarding its state machine, not an infrastructure failure.
Source
Thrown at v3/@claude-flow/swarm/src/domain/entities/agent.ts:194
/**
* Start the agent (transition to active)
*/
start(): void {
if (this._status === 'terminated') {
throw new Error('Cannot start terminated agent');
}
this._status = 'active';
this._lastActiveAt = new Date();
this._updatedAt = new Date();
}
/**
* Pause the agent
*/
pause(): void {
if (this._status !== 'active' && this._status !== 'busy') {
throw new Error('Can only pause active or busy agent');
}
this._status = 'paused';
this._updatedAt = new Date();
}
/**
* Resume paused agent
*/
resume(): void {
if (this._status !== 'paused') {
throw new Error('Can only resume paused agent');
}
this._status = this._currentTaskIds.size > 0 ? 'busy' : 'active';
this._lastActiveAt = new Date();
this._updatedAt = new Date();
}
/**View on GitHub (pinned to fa13ee4ad6)
Solutions
- Check agent.status is 'active' or 'busy' before calling pause() (public status getter) Make pause idempotent in your layer: skip if already 'paused' For an 'error' agent, recover() first (to idle), then start(), then pause() if still needed Serialize lifecycle commands per agent (queue or lock) to avoid races
Example fix
// before
function onOperatorPause(agent) { agent.pause(); } // throws when idle/paused/error
// after
function onOperatorPause(agent) {
if (agent.status === 'active' || agent.status === 'busy') agent.pause();
// already-paused / other states: no-op
} Defensive patterns
Strategy: type-guard
Validate before calling
const pauseable = (a) => a.status === 'active' || a.status === 'busy'; if (pauseable(agent)) agent.pause();
Type guard
function isPauseable(a) { return a.status === 'active' || a.status === 'busy'; } Try / catch
try { agent.pause(); }
catch (e) {
if (e instanceof Error && e.message === 'Can only pause active or busy agent') return; // wrong state — no-op
throw e;
} Prevention
- Drive UI/scheduler pause actions from the agent's current status
- Serialize lifecycle commands per agent to avoid double-pause races
- Remember recover()->start()->pause() is the only path back from 'error' to pausable
When it happens
Trigger: Pausing an idle agent (it was created but never started) Calling pause() twice in a row (second call sees status 'paused') Pausing an agent in 'error' state (after fail() was called) before recover() Pausing a terminated agent Concurrent lifecycle commands from a UI and a coordinator both issuing pause
Common situations: UI pause buttons wired directly to agent.pause() without rendering/disabling based on current status Reconciliation loops that pause everything during deploy without filtering by state Race between an agent erroring out and an operator pausing it
Related errors
- Cannot start terminated agent
- Can only resume paused agent
- Can only recover from error state
- Cannot assign task to terminated agent
- Task ${taskId} not assigned to this agent
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/5e2c34d49cdcc8d0.
Report an issue: GitHub.