ruvnet/ruflo · error

Consensus is disabled

Error message

Consensus is disabled

What it means

Thrown by FederationHub.propose() when the hub was constructed with enableConsensus false (or the flag not set). propose() is the entry point for federation-wide consensus, so the guard rejects any consensus attempt on a hub that was never configured for it. The check runs before the proposal object is created, so no state is mutated.

Source

Thrown at v3/@claude-flow/swarm/src/federation-hub.ts:668

  getMessages(limit: number = 100): FederationMessage[] {
    return this.messages.slice(-limit);
  }

  // ==========================================================================
  // Federation Consensus
  // ==========================================================================

  /**
   * Propose a value for federation-wide consensus
   */
  async propose(
    proposerId: SwarmId,
    type: string,
    value: unknown,
    timeoutMs: number = 30000
  ): Promise<ConsensusProposal> {
    if (!this.config.enableConsensus) {
      throw new Error('Consensus is disabled');
    }

    const proposal: ConsensusProposal = {
      id: `proposal_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      proposerId,
      type,
      value,
      votes: new Map([[proposerId, true]]),
      status: 'pending',
      createdAt: new Date(),
      expiresAt: new Date(Date.now() + timeoutMs),
    };

    this.proposals.set(proposal.id, proposal);
    this.stats.consensusProposals++;
    this.emitEvent('consensus_started', proposerId);

    // Request votes from all active swarms

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Set enableConsensus: true in the FederationHubConfig passed to the FederationHub constructor, before calling propose()
  2. Verify the config object you build is the one the hub receives; partial spreads or merges with defaults can silently drop the flag
  3. If federation-wide consensus is not needed, replace propose() calls with direct peer or message-bus coordination APIs

Example fix

// before
const hub = new FederationHub({ nodeId: 'node-1' });
await hub.propose(proposerId, 'deploy', { region: 'eu' }); // throws: Consensus is disabled

// after
const hub = new FederationHub({ nodeId: 'node-1', enableConsensus: true });
await hub.propose(proposerId, 'deploy', { region: 'eu' });
Defensive patterns

Strategy: validation

Validate before calling

function assertConsensusAvailable(config: { enableConsensus?: boolean }): void {
  if (!config.enableConsensus) {
    throw new Error('FederationHub consensus is disabled: set enableConsensus: true before calling propose()');
  }
}

assertConsensusAvailable(hubConfig);
await hub.propose(proposerId, type, value);

Type guard

function canPropose(config: { enableConsensus?: boolean }): boolean {
  return config.enableConsensus === true;
}

Try / catch

try {
  await hub.propose(proposerId, type, value);
} catch (err) {
  if (err instanceof Error && err.message === 'Consensus is disabled') {
    // configuration problem, not transient: use non-consensus coordination
    return fallbackToDirectCoordination();
  }
  throw err;
}

Prevention

When it happens

Trigger: Constructing a FederationHub with a config that lacks enableConsensus: true, then calling await hub.propose(proposerId, type, value). Any wrapper that forwards proposals to the hub (federation coordinators, consensus clients) hits the same guard.

Common situations: Copying a minimal FederationHubConfig sample that omits the flag; consensus disabled for performance in one environment and that config reused where propose() is called; version upgrades that introduce the flag with old configs defaulting to disabled.

Related errors


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