ruvnet/ruflo · error

no eligible peers for exploration

Error message

no eligible peers for exploration

What it means

Thrown by MctsExplorer.explore in @claude-flow/browser when pickPeer() cannot find any peer adapter to run the root (or child) branch. pickPeer() filters this.peers against this.peerBlacklist and returns null when the eligible list is empty, so the error means either zero peers were configured or every peer has been blacklisted (typically after failures).

Solutions

  1. Ensure at least one non-blacklisted PeerAdapter is passed in the MctsExplorer options.peers array before calling explore()
  2. Inspect/clear peerBlacklist for peers that have recovered (re-enable or re-register them) before starting a new run
  3. Add redundancy: configure multiple peers so a single blacklisted peer does not empty the eligible set
  4. Pre-check eligibility before exploring (peers.some(p => !blacklist.has(p.id))) and surface a clearer configuration error

Example fix

// before
const explorer = new MctsExplorer({ peers: [] , ...opts });
await explorer.explore({ rootAction, goal, expansionPolicy }); // throws

// after
const explorer = new MctsExplorer({ peers: [localPeer, remotePeer], ...opts });
if (!explorer.peers.some(p => !explorer.peerBlacklist.has(p.id))) {
  throw new Error('configure healthy peers before exploration');
}
await explorer.explore({ rootAction, goal, expansionPolicy });
Defensive patterns

Strategy: validation

Validate before calling

const eligible = explorer.peers.filter(p => !explorer.peerBlacklist.has(p.id));
if (eligible.length === 0) {
  throw new Error('MCTS explore aborted: all peers blacklisted or none configured');
}
await explorer.explore({ rootAction, goal, expansionPolicy });

Type guard

const hasEligiblePeer = (x: { peers: PeerAdapter[]; peerBlacklist: Set<string> }): boolean =>
  x.peers.some(p => !x.peerBlacklist.has(p.id));

Try / catch

try { await explorer.explore(input); } catch (e) { if (e instanceof Error && e.message === 'no eligible peers for exploration') { /* clear blacklist for recovered peers or register new peers */ } throw e; }

Prevention

When it happens

Trigger: Constructing MctsExplorer with an empty peers array and calling explore(); or all configured peers having been added to peerBlacklist (e.g. after repeated execution failures) so eligible.filter(p => !peerBlacklist.has(p.id)) yields nothing at the root branch creation.

Common situations: Running MCTS exploration in a single-node setup with no peer adapters registered; peers going unhealthy mid-run and getting blacklisted, then a subsequent explore() call failing immediately; forgetting to re-register recovered peers after an outage.


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

Appendix: source

Thrown at v3/@claude-flow/browser/src/application/mcts-explorer.ts:88

    this.peers = options.peers;
    this.scorer = options.scorer;
    this.maxDepth = options.maxDepth ?? 5;
    this.maxBranches = options.maxBranches ?? 32;
    this.defaultPeerBudgetUsd = options.defaultPeerBudgetUsd ?? 1.0;
    this.ucb = options.ucb ?? { c: Math.SQRT2 };
    this.trustedPublicKeys = options.trustedPublicKeys ?? [];
  }

  /** Explore from a seed root action. Returns the winning branch's ID + aggregate stats. */
  async explore(input: {
    rootAction: RootAction;
    goal: string;
    expansionPolicy: ExpansionPolicy;
  }): Promise<MctsRunResult> {
    const runId = 'run-' + Date.now() + '-' + randomBytes(3).toString('hex');
    const rootId = 'br-root-' + randomBytes(3).toString('hex');
    const rootPeer = this.pickPeer();
    if (!rootPeer) throw new Error('no eligible peers for exploration');

    const root: McTsBranch = McTsBranchSchema.parse({
      id: rootId,
      runId,
      parentId: null,
      peerId: rootPeer.id,
      action: input.rootAction.action,
      input: input.rootAction.input,
      depth: 0,
      visits: 0,
      totalValue: 0,
      status: 'pending',
      costUsd: 0,
      createdAt: new Date().toISOString(),
    });
    this.branches.set(rootId, root);

    // Execute and expand iteratively. Counter is # of EXECUTIONS (not # of

View on GitHub (pinned to fa13ee4ad6)