{"record":{"id":"26621b7eb5ac0ac8","repo":"ruvnet/ruflo","slug":"no-active-nodes-available-for-leader-election","errorCode":null,"errorMessage":"No active nodes available for leader election","messagePattern":"No active nodes available for leader election","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/swarm/src/topology-manager.ts","lineNumber":232,"sourceCode":"      }\n    }\n\n    // For mesh/hybrid, elect based on node capabilities\n    const candidates = this.state.nodes\n      .filter(n => n.status === 'active')\n      .sort((a, b) => {\n        // Prefer coordinators, then queens\n        const roleOrder: Record<TopologyNode['role'], number> = {\n          queen: 0,\n          coordinator: 1,\n          worker: 2,\n          peer: 2,\n        };\n        return roleOrder[a.role] - roleOrder[b.role];\n      });\n\n    if (candidates.length === 0) {\n      throw new Error('No active nodes available for leader election');\n    }\n\n    const leader = candidates[0];\n    this.state.leader = leader.agentId;\n\n    this.emit('leader.elected', { leaderId: leader.agentId });\n\n    return leader.agentId;\n  }\n\n  async rebalance(): Promise<void> {\n    const now = new Date();\n    const timeSinceLastRebalance = now.getTime() - this.lastRebalance.getTime();\n\n    // Prevent too frequent rebalancing\n    if (timeSinceLastRebalance < 5000) {\n      return;\n    }","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/swarm/src/topology-manager.ts#L214-L250","documentation":"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.","triggerScenarios":"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.","commonSituations":"Restart storms where nodes rejoin in syncing state; status fields lagging behind reality after disconnects; partitions isolating the entire remainder of the swarm.","solutions":["Restore node health first: updateNode(agentId, { status: 'active' }) or let the join protocol finish before electing","Delay re-election until at least one node reports active (subscribe to node status events)","Investigate why statuses are not active; mass offline usually means an infra or network issue"],"exampleFix":"// before\nawait topology.electLeader(); // throws: all nodes offline after restart\n\n// after\nawait waitForNodeStatus(topology, 'active', 1); // poll or subscribe to node.updated\nawait topology.electLeader();","handlingStrategy":"retry","validationCode":"function activeNodeCount(topology: TopologyManager): number {\n  return topology.getState().nodes.filter(n => n.status === 'active').length;\n}\n\nif (activeNodeCount(topology) === 0) {\n  // bring at least one node back to eligible status before electing\n  await topology.updateNode(firstRejoinedAgentId(topology), { status: 'active' });\n}\nawait topology.electLeader();","typeGuard":null,"tryCatchPattern":"try {\n  await topology.electLeader();\n} catch (err) {\n  if (err instanceof Error && err.message === 'No active nodes available for leader election') {\n    await delay(backoffMs); // nodes may still be transitioning to active\n    return topology.electLeader();\n  }\n  throw err;\n}","preventionTips":["Wait for a barrier of at least one active node before electing after restarts","Monitor node status distribution and alert when active count is zero","Keep heartbeats updating node status so the candidate filter sees reality"],"tags":["leader-election","node-health","availability","quorum"],"backgroundTag":"quorum-unavailable","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}