ruvnet/ruflo · error · Error
Unknown consensus algorithm
Error message
Unknown consensus algorithm: ${this.config.algorithm} What it means
ConsensusEngine.initialize() switches on config.algorithm and constructs the matching implementation: 'raft', 'byzantine', 'gossip', or 'paxos' (which aliases Raft with similar guarantees). Any other value reaches the default branch and throws during initialization, before an implementation is ever created. The default when algorithm is omitted is 'raft'.
Solutions
- Set algorithm to one of the supported values: 'raft' | 'byzantine' | 'gossip' | 'paxos' (or omit it — default is 'raft').
- Validate the value against that allowlist at config load time, before constructing the engine.
- If you need BFT semantics, use 'byzantine'; 'paxos' silently maps to Raft — pick 'raft' explicitly for clarity.
- Check the package version's ConsensusAlgorithm type — the union is the source of truth.
Example fix
// before
const engine = new ConsensusEngine('n1', { algorithm: 'bft' }); // typo
await engine.initialize(); // throws: Unknown consensus algorithm
// after
const engine = new ConsensusEngine('n1', { algorithm: 'byzantine' }); // raft | byzantine | gossip | paxos
await engine.initialize(); Defensive patterns
Strategy: validation
Validate before calling
const ALGORITHMS = ['raft', 'byzantine', 'gossip', 'paxos'];
if (!ALGORITHMS.includes(config.algorithm)) {
throw new Error(`algorithm must be one of ${ALGORITHMS.join(', ')}, got '${config.algorithm}'`);
}
const engine = new ConsensusEngine(nodeId, config);
await engine.initialize(); Type guard
const ALGORITHMS = ['raft', 'byzantine', 'gossip', 'paxos'] as const;
export type KnownAlgorithm = (typeof ALGORITHMS)[number];
function isKnownAlgorithm(a: string): a is KnownAlgorithm {
return (ALGORITHMS as readonly string[]).includes(a);
} Try / catch
try {
await engine.initialize(config);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Unknown consensus algorithm:')) {
// fall back to the default 'raft' or fail config load with a clear message
} else {
throw e;
}
} Prevention
- Validate algorithm against the ConsensusAlgorithm union at config load time (zod/manual allowlist).
- Remember 'paxos' silently maps to Raft — prefer explicit 'raft'.
- Re-check the supported union after package upgrades.
When it happens
Trigger: A typo in config.algorithm such as 'bft' or 'raftv2'; a value loaded from an env var with wrong casing ('Raft'); a version upgrade that renamed or removed an algorithm name; config JSON passing an arbitrary string without validation.
Common situations: Algorithm chosen from user input or config files without an allowlist; docs/example drift between package versions; copy-pasted configs from other libraries (e.g. 'pbft' instead of 'byzantine').
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Consensus engine not initialized
- Consensus is disabled
- HTTP transport requires host and port configuration
- HTTP transport requires host and port configuration
- Unknown transport type
AI-assisted analysis of ruvnet/ruflo@2602b642d9 (2026-08-18).
Data as JSON: /api/errors/e03d7385b17fc995.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/swarm/src/consensus/index.ts:117
threshold: this.config.threshold,
timeoutMs: this.config.timeoutMs,
maxRounds: this.config.maxRounds,
requireQuorum: this.config.requireQuorum,
});
break;
case 'paxos':
// Fall back to Raft for Paxos (similar guarantees)
this.implementation = createRaftConsensus(this.nodeId, {
threshold: this.config.threshold,
timeoutMs: this.config.timeoutMs,
maxRounds: this.config.maxRounds,
requireQuorum: this.config.requireQuorum,
});
break;
default:
throw new Error(`Unknown consensus algorithm: ${this.config.algorithm}`);
}
await this.implementation.initialize();
// Forward events
this.implementation.on('consensus.achieved', (data) => {
this.emit('consensus.achieved', data);
});
this.implementation.on('leader.elected', (data) => {
this.emit('leader.elected', data);
});
this.emit('initialized', {
nodeId: this.nodeId,
algorithm: this.config.algorithm
});
}View on GitHub (pinned to 2602b642d9)