ruvnet/ruflo · error

No active nodes available for leader election

Error message

No active nodes available for leader election

What it means

The general election path filters nodes down to eligible candidates, sorts them queen over coordinator over worker/peer, and throws when the filter yields zero. Unlike the empty-topology error, nodes exist here but none qualify, typically all offline, degraded, or still syncing. It signals a health or availability problem, not an election bug.

Source

Thrown at v3/@claude-flow/swarm/src/topology-manager.ts:232

      }
    }

    // For mesh/hybrid, elect based on node capabilities
    const candidates = this.state.nodes
      .filter(n => n.status === 'active')
      .sort((a, b) => {
        // Prefer coordinators, then queens
        const roleOrder: Record<TopologyNode['role'], number> = {
          queen: 0,
          coordinator: 1,
          worker: 2,
          peer: 2,
        };
        return roleOrder[a.role] - roleOrder[b.role];
      });

    if (candidates.length === 0) {
      throw new Error('No active nodes available for leader election');
    }

    const leader = candidates[0];
    this.state.leader = leader.agentId;

    this.emit('leader.elected', { leaderId: leader.agentId });

    return leader.agentId;
  }

  async rebalance(): Promise<void> {
    const now = new Date();
    const timeSinceLastRebalance = now.getTime() - this.lastRebalance.getTime();

    // Prevent too frequent rebalancing
    if (timeSinceLastRebalance < 5000) {
      return;
    }

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Restore node health first: updateNode(agentId, { status: 'active' }) or let the join protocol finish before electing
  2. Delay re-election until at least one node reports active (subscribe to node status events)
  3. Investigate why statuses are not active; mass offline usually means an infra or network issue

Example fix

// before
await topology.electLeader(); // throws: all nodes offline after restart

// after
await waitForNodeStatus(topology, 'active', 1); // poll or subscribe to node.updated
await topology.electLeader();
Defensive patterns

Strategy: retry

Validate before calling

function activeNodeCount(topology: TopologyManager): number {
  return topology.getState().nodes.filter(n => n.status === 'active').length;
}

if (activeNodeCount(topology) === 0) {
  // bring at least one node back to eligible status before electing
  await topology.updateNode(firstRejoinedAgentId(topology), { status: 'active' });
}
await topology.electLeader();

Try / catch

try {
  await topology.electLeader();
} catch (err) {
  if (err instanceof Error && err.message === 'No active nodes available for leader election') {
    await delay(backoffMs); // nodes may still be transitioning to active
    return topology.electLeader();
  }
  throw err;
}

Prevention

When it happens

Trigger: Every node has a non-eligible status when electLeader() runs; elections immediately after a mass restart while nodes are still in syncing status; all eligible nodes lost to a network partition.

Common situations: Restart storms where nodes rejoin in syncing state; status fields lagging behind reality after disconnects; partitions isolating the entire remainder of the swarm.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/26621b7eb5ac0ac8. Report an issue: GitHub.