ruvnet/ruflo · error · Error
Agent has ${currentTasks} active tasks. Use force=true to te
Error message
Agent has ${currentTasks} active tasks. Use force=true to terminate anyway. What it means
TerminateAgentCommandHandler refuses to terminate an agent whose currentTaskCount > 0 unless input.force === true, protecting in-flight tasks from being orphaned. The message itself documents the escape hatch: re-issue the command with force=true when losing active work is acceptable.
Source
Thrown at v3/@claude-flow/swarm/src/application/commands/spawn-agent.command.ts:110
tasksReassigned: number;
}
/**
* Terminate Agent Command Handler
*/
export class TerminateAgentCommandHandler {
constructor(private readonly repository: IAgentRepository) {}
async execute(input: TerminateAgentInput): Promise<TerminateAgentResult> {
const agent = await this.repository.findById(input.agentId);
if (!agent) {
throw new Error(`Agent '${input.agentId}' not found`);
}
const currentTasks = agent.currentTaskCount;
if (currentTasks > 0 && !input.force) {
throw new Error(`Agent has ${currentTasks} active tasks. Use force=true to terminate anyway.`);
}
agent.terminate();
await this.repository.save(agent);
return {
success: true,
agentId: input.agentId,
tasksReassigned: currentTasks,
};
}
}
View on GitHub (pinned to fa13ee4ad6)
Solutions
- Let the agent's tasks complete (or reassign them) and terminate again without force.
- If losing in-flight work is acceptable, re-send the command with force: true.
- Cancel the agent's outstanding tasks first, then terminate.
- In shutdown paths, drain or reassign task queues before terminating agents.
Example fix
// before
await terminateAgent.execute({ agentId }); // agent has N active tasks
// after — option A: accept losing in-flight tasks
await terminateAgent.execute({ agentId, force: true });
// after — option B: drain first, then terminate normally
await drainOrReassignTasks(agentId);
await terminateAgent.execute({ agentId }); Defensive patterns
Strategy: validation
Validate before calling
const agent = await agentRepository.findById(agentId);
if (!agent) throw new Error(`unknown agent ${agentId}`);
const force = agent.currentTaskCount > 0 && inFlightWorkIsExpendable;
if (agent.currentTaskCount > 0 && !force) {
await drainOrReassignTasks(agentId); // wait for tasks first
}
await terminateAgentHandler.execute({ agentId, force }); Try / catch
try {
await terminateAgentHandler.execute({ agentId });
} catch (e) {
if (e instanceof Error && e.message.includes('active tasks. Use force=true')) {
// either drain/reassign tasks and retry without force,
// or retry once with force: true if losing the work is acceptable
} else {
throw e;
}
} Prevention
- Drain or reassign tasks before terminating agents in orchestration code.
- Reserve force: true for shutdown/incident paths and log whenever it is used.
- Check currentTaskCount before issuing terminate so the decision is explicit, not exceptional.
When it happens
Trigger: Terminating a busy agent without force while it still holds tasks; tasks that are stuck and never complete, blocking cleanup; a shutdown script that does not drain agent work queues first; scale-down logic selecting agents at random regardless of load.
Common situations: Autoscaler scale-down picking busy agents; operators killing agents during an incident with queued work; tests terminating agents without force while mock tasks are assigned.
Related errors
- Agent not found: ${agentId}
- Agent '${input.agentId}' not found
- task step ${step.stepId} requires config.agentId or workflow
- agent_execute failed
- Agent ${this.id} is not available (status: ${this.status})
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/0545d1620a94b783.
Report an issue: GitHub.