ruvnet/ruflo · error · Error

Unknown consensus algorithm: ${this.config.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'.

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 fa13ee4ad6)

Solutions

  1. Set algorithm to one of the supported values: 'raft' | 'byzantine' | 'gossip' | 'paxos' (or omit it — default is 'raft').
  2. Validate the value against that allowlist at config load time, before constructing the engine.
  3. If you need BFT semantics, use 'byzantine'; 'paxos' silently maps to Raft — pick 'raft' explicitly for clarity.
  4. 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

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').

Related errors


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