ruvnet/ruflo · error · Error

Consensus engine not initialized

Error message

Consensus engine not initialized

What it means

ConsensusEngine creates its implementation lazily inside initialize(); every other method assumes it exists. addNode() throws 'Consensus engine not initialized' when this.implementation is still undefined — i.e. when addNode runs before await initialize() completes, or after initialize() rejected (for example on an unknown algorithm) leaving the engine empty.

Source

Thrown at v3/@claude-flow/swarm/src/consensus/index.ts:146

      this.emit('leader.elected', data);
    });

    this.emit('initialized', {
      nodeId: this.nodeId,
      algorithm: this.config.algorithm
    });
  }

  async shutdown(): Promise<void> {
    if (this.implementation) {
      await this.implementation.shutdown();
    }
    this.emit('shutdown');
  }

  addNode(nodeId: string, options?: { isPrimary?: boolean }): void {
    if (!this.implementation) {
      throw new Error('Consensus engine not initialized');
    }

    if (this.implementation instanceof RaftConsensus) {
      this.implementation.addPeer(nodeId);
    } else if (this.implementation instanceof ByzantineConsensus) {
      this.implementation.addNode(nodeId, options?.isPrimary);
    } else if (this.implementation instanceof GossipConsensus) {
      this.implementation.addNode(nodeId);
    }
  }

  removeNode(nodeId: string): void {
    if (!this.implementation) {
      return;
    }

    if (this.implementation instanceof RaftConsensus) {
      this.implementation.removePeer(nodeId);

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. await engine.initialize(config) before any addNode/propose/vote call.
  2. If initialize() rejected, read and fix the original error (e.g. unknown algorithm), then initialize again before using the engine.
  3. Structure boot as: construct → await initialize → register nodes → operate.
  4. Wrap the engine in a facade that queues node registrations until initialization resolves.

Example fix

// before
const engine = new ConsensusEngine('n1', { algorithm: 'raft' });
engine.addNode('n2'); // throws: not initialized

// after
const engine = new ConsensusEngine('n1', { algorithm: 'raft' });
await engine.initialize();
engine.addNode('n2');
Defensive patterns

Strategy: validation

Validate before calling

// every API is safe only after initialize() resolves
let ready = false;
engine.on('initialized', () => { ready = true; });
await engine.initialize(config); // throws here on bad config, not later
if (!ready) throw new Error('consensus engine failed to initialize');
engine.addNode('n2');

Try / catch

try {
  engine.addNode(nodeId);
} catch (e) {
  if (e instanceof Error && e.message === 'Consensus engine not initialized') {
    await engine.initialize(config); // then retry addNode
    engine.addNode(nodeId);
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling engine.addNode(...) immediately after the constructor without awaiting initialize(); initialize() threw (invalid algorithm) and the caller ignored the rejection; tests constructing the engine and registering nodes in beforeEach without init.

Common situations: Missing await on initialize() in async boot code; fire-and-forget initialization; error from initialize swallowed so later calls fail confusingly with 'not initialized' instead of the root cause.

Related errors


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