ruvnet/ruflo · error · Error
no eligible peers for exploration
Error message
no eligible peers for exploration
What it means
Thrown by MctsExplorer.explore() at the very start of a run when pickPeer() returns null. pickPeer filters peers against the peerBlacklist set, so this fires when every peer passed to the constructor has since been blacklisted. The constructor already rejects an empty peers array with a different message, so this specific error means peers existed at construction but none are now eligible (budget exhausted, bad signatures, or a prior run poisoned the explorer's mutable state).
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 # ofView on GitHub (pinned to 6b01dc5a68)
Solutions
- Construct a fresh MctsExplorer (new MctsExplorer(options)) for each explore() call so blacklist/spend state does not leak between runs.
- Before exploring, verify options.peers has length > 0 and that at least one peer has budgetUsd > 0 (or defaultPeerBudgetUsd > 0).
- If using trustedPublicKeys, ensure every peer signs with a key in that list; otherwise leave trustedPublicKeys unset to accept any valid signature.
- Raise defaultPeerBudgetUsd or each peer's budgetUsd so a single run cannot exhaust all peers.
Example fix
// before
const explorer = new MctsExplorer({ peers, scorer });
await explorer.explore({ rootAction, goal, expansionPolicy });
await explorer.explore({ rootAction: another, goal, expansionPolicy }); // throws 60
// after — fresh explorer per run
function runMcts(peers, scorer, input) {
const explorer = new MctsExplorer({ peers, scorer });
return explorer.explore(input);
} Defensive patterns
Strategy: validation
Validate before calling
function hasEligiblePeer(opts) {
return Array.isArray(opts.peers)
&& opts.peers.length > 0
&& opts.peers.some(p => (p.budgetUsd ?? opts.defaultPeerBudgetUsd ?? 1.0) > 0);
}
// before explore:
if (!hasEligiblePeer(options)) throw new Error('configure at least one peer with positive budget'); Type guard
null
Try / catch
null
Prevention
- Construct a new MctsExplorer per run; blacklist/spend state is instance-scoped and never reset.
- Pin trustedPublicKeys to the keys your peers actually sign with, or leave it empty to accept any valid signature.
- Set defaultPeerBudgetUsd high enough that one run cannot exhaust every peer.
When it happens
Trigger: Calling explorer.explore() on an explorer instance that has already completed a run where every peer was blacklisted (budget exhausted or invalid trajectory signatures). Also fired when constructing the explorer with peers whose budgetUsd is 0, or when reusing a single MctsExplorer instance across runs because peerBlacklist, peerSpend, and peerSignatureBlacklist are instance fields that accumulate across explore() calls.
Common situations: Sharing one MctsExplorer across many runs without realizing the blacklist is never cleared; setting defaultPeerBudgetUsd to 0; a federation where all peers return Ed25519 signatures not in trustedPublicKeys (so they get signature-blacklisted after the first call).
Related errors
- Darwin archive exceeded candidate-count budget
- Darwin archive exceeded evaluation-cost budget
- Invalid completion type
- MctsExplorer requires at least one peer
- trajectory envelope not found: ${path}
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/7a3ec24cf8c5f162.
Report an issue: GitHub.