ruvnet/ruflo · error
Consensus is disabled
Error message
Consensus is disabled
What it means
FederationHub.propose() throws immediately when the hub was configured with enableConsensus: false — no federation-wide vote is created and the proposal never reaches peers. Consensus (propose/vote/decide across federated swarms) is an opt-out feature that defaults to true, so this error means the running configuration explicitly disabled it.
Source
Thrown at v3/@claude-flow/swarm/src/federation-hub.js:435
}
}
return sent;
}
/**
* Get recent messages
*/
getMessages(limit = 100) {
return this.messages.slice(-limit);
}
// ==========================================================================
// Federation Consensus
// ==========================================================================
/**
* Propose a value for federation-wide consensus
*/
async propose(proposerId, type, value, timeoutMs = 30000) {
if (!this.config.enableConsensus) {
throw new Error('Consensus is disabled');
}
const proposal = {
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
await this.broadcast(proposerId, {
type: 'vote_request',
proposalId: proposal.id,View on GitHub (pinned to fa13ee4ad6)
Solutions
- Set enableConsensus: true in the FederationHub config where federation-wide decisions are needed
- If consensus must stay disabled, guard the call site: check the hub config / feature flag before propose()
- Audit the effective config after construction (log this.config or the merged result) to confirm the flag's actual value
- Keep one source of truth for the flag (env or config service) instead of duplicating it per environment
Example fix
// before
const hub = new FederationHub({ ...opts, enableConsensus: false });
await hub.propose(this.id, 'scale-up', { nodes: 3 }); // throws 'Consensus is disabled'
// after
const hub = new FederationHub({ ...opts, enableConsensus: true });
await hub.propose(this.id, 'scale-up', { nodes: 3 });
// or gate the call:
if (hub.config.enableConsensus !== false) {
await hub.propose(this.id, 'scale-up', { nodes: 3 });
} else {
applyLocally({ nodes: 3 }); // non-consensus fallback path
} Defensive patterns
Strategy: validation
Validate before calling
// Check the flag through the hub's exposed config before proposing:
if (hub.config?.enableConsensus === false) {
return applyLocalDecision(value); // skip consensus path entirely
}
await hub.propose(proposerId, type, value); Type guard
function consensusEnabled(hub) { return hub.config?.enableConsensus !== false; } // default true Try / catch
try { await hub.propose(id, type, value); }
catch (e) {
if (e instanceof Error && e.message === 'Consensus is disabled') {
return fallbackToSingleHubDecision(value); // explicit degraded mode
}
throw e;
} Prevention
- Log the effective enableConsensus value after hub construction to catch config-merge surprises
- Keep the flag in one config source per environment (env var / config service)
- Feature-detect before calling: guard propose() behind the same flag the hub was built with
- When disabling consensus, audit call sites (coordinators, scale routines) that assume propose() works
When it happens
Trigger: new FederationHub({ enableConsensus: false }) (or a config merge that evaluated the flag false) followed by any hub.propose(...) call Deployments that copied a minimal config object overriding defaults — the constructor spreads DEFAULT_CONFIG, but any explicit false wins Feature-flag/config drift between environments: consensus disabled in staging config, code path still calls propose() Shared coordinator code (e.g., unified-coordinator) that always calls propose() while some hubs run without consensus
Common situations: Operators disabling consensus for 'single-hub mode' or to cut overhead, later enabling features that need it Config templating tools that serialize all booleans explicitly, turning the default-true into explicit false by accident Version upgrades where a previously unguarded propose() call now runs against a consensus-disabled hub
Related errors
- Consensus is disabled
- WG mesh layer not initialized (set config.wgMesh = true and
- Unsupported federation signature mode: ${String(signatureMod
- Unknown consensus algorithm: ${this.config.algorithm}
- SSRF guard: invalid URL — ${rawUrl}
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/b60b7ff65ffd6db6.
Report an issue: GitHub.