ruvnet/ruflo · error · Error
MctsExplorer requires at least one peer
Error message
MctsExplorer requires at least one peer
What it means
Constructor guard in MctsExplorer: it refuses to build an explorer whose options.peers is an empty array. The Monte-Carlo Tree Search exploration requires at least one peer to expand/roll out branches against, and the rest of the options (maxDepth, maxBranches, ucb.c, defaultPeerBudgetUsd, trustedPublicKeys) all default sensibly, but peers has no default and cannot be empty.
Source
Thrown at v3/@claude-flow/browser/src/application/mcts-explorer.ts:69
trajectoryEnvelope: unknown,
) => Promise<RootAction[]>;
export class MctsExplorer {
private readonly peers: PeerAdapter[];
private readonly scorer: ValueScorer;
private readonly maxDepth: number;
private readonly maxBranches: number;
private readonly defaultPeerBudgetUsd: number;
private readonly ucb: UcbParams;
private readonly trustedPublicKeys: string[];
private branches: Map<string, McTsBranch> = new Map();
private peerSpend: Map<string, number> = new Map();
private peerBlacklist: Set<string> = new Set();
private peerSignatureBlacklist: Set<string> = new Set();
constructor(options: MctsExplorerOptions) {
if (options.peers.length === 0) throw new Error('MctsExplorer requires at least one peer');
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();View on GitHub (pinned to 6b01dc5a68)
Solutions
- Ensure options.peers has at least one entry before constructing the explorer; gate construction on peers.length > 0.
- Run peer discovery/trust filtering after, not before, you have a non-empty candidate set.
- If zero peers is a legitimate runtime state, skip constructing the explorer (return null / a no-op explorer) rather than passing [].
- Add a config validation step that fails fast with a clearer message when the peers source is empty.
Example fix
// before
const explorer = new MctsExplorer({ peers: filteredPeers, scorer }); // throws if filteredPeers=[]
// after
if (filteredPeers.length === 0) {
throw new Error("no trusted peers available after filtering; cannot run MCTS exploration");
}
const explorer = new MctsExplorer({ peers: filteredPeers, scorer }); Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(peers) || peers.length === 0) {
throw new Error("MctsExplorer needs >=1 peer; got 0");
}
return new MctsExplorer({ peers, scorer }); Type guard
function isNonEmptyPeerList(x: unknown): x is unknown[] {
return Array.isArray(x) && x.length > 0;
} Prevention
- Gate construction on peers.length > 0; return a no-op explorer when zero peers is a legitimate runtime state.
- Run peer discovery before constructing the explorer, not after filtering to empty.
- Fail fast in config loading when the peers source is unset, with a clearer message than the constructor's.
When it happens
Trigger: new MctsExplorer({ peers: [], ... }) — e.g. the peer list was filtered down to zero by peerBlacklist/signature checks before construction, or a config loader returned an empty peers array.
Common situations: Initialising the explorer before the peer-discovery/allowlist step has populated peers; a config/env var that lists peers being unset; all configured peers failing a trust/public-key filter upstream so the array handed to the constructor is empty.
Related errors
- SemanticRouter requires a dimension in config
- unknown game "${key}". Known: ${Object.keys(GAMES).join(', '
- unknown strategy "${name}". Available: ${roster.map((r) => r
- Invalid completion type
- Invalid hostname
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/f4ef1e8d474e7323.
Report an issue: GitHub.