ruvnet/ruflo · error
peer registry is full
Error message
peer registry is full (${MAX_PEERS}) What it means
addPeer() enforces a maximum peer count (MAX_PEERS) on the federation peer registry file to bound file size and sync cost. When the registry already holds MAX_PEERS entries, adding another is refused. Removing an existing peer first is required to free a slot.
Solutions
- List current peers and remove stale/unused ones (e.g. via removePeer) to free a slot, then re-run addPeer.
- Raise MAX_PEERS if your deployment legitimately needs more peers (edit the constant and redeploy).
- Deduplicate before adding: check whether the nodeId already exists and skip addPeer for known peers.
- Audit the registry file for leaked duplicate/stale entries from failed automations and clean it.
Example fix
// before
addPeer(base, { nodeId, url, publicKey }); // throws when full
// after
const peers = readPeers(base);
if (!peers.some(p => p.nodeId === nodeId)) {
if (peers.length >= MAX_PEERS) removePeer(base, oldestPeer.nodeId);
addPeer(base, { nodeId, url, publicKey });
} Defensive patterns
Strategy: try-catch
Validate before calling
const peers = readPeers(basePath);
if (peers.length >= MAX_PEERS) throw new Error('peer registry full: remove peers before adding'); Try / catch
try {
addPeer(basePath, input);
} catch (e) {
if (/peer registry is full/.test(e.message)) {
removePeer(basePath, selectStalePeer().nodeId);
addPeer(basePath, input);
} else throw e;
} Prevention
- Track registry size and alert before hitting MAX_PEERS
- Remove peer entries during node decommissioning
- Idempotently skip addPeer for already-known nodeIds
- Avoid re-adding all peers on every deploy
When it happens
Trigger: Calling addPeer() when readPeers(basePath) returns peers.length >= MAX_PEERS — i.e. every slot in peers.json is occupied and one more peer is requested.
Common situations: Long-running federation clusters that accumulated peers over time; automated tooling re-adding peers on each deploy without deduplication; leaked/stale entries from decommissioned nodes never removed.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Agent has reached max concurrent tasks
- channel must be pub: or prv:<16 hex>
- claim rejected ( )
- Concurrent write detected on aggregate
- Consensus is disabled
AI-assisted analysis of ruvnet/ruflo@2602b642d9 (2026-09-15).
Data as JSON: /api/errors/728dd74916b6be68.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/mcp-tools/agentbbs-federation.ts:269
let u: URL;
try { u = new URL(raw); } catch { throw new Error('peer url is not a valid URL'); }
if (u.protocol !== 'http:' && u.protocol !== 'https:') {
throw new Error('peer url must be http or https');
}
if (u.username || u.password) throw new Error('peer url must not embed credentials');
return u.origin;
}
export function addPeer(
basePath: string,
input: { nodeId: string; url: string; publicKey: string; label?: string },
): FederationPeer {
if (!NODE_ID_RE.test(input.nodeId ?? '')) throw new Error('nodeId must be 16 lowercase hex chars');
if (!HEX64_RE.test(input.publicKey ?? '')) throw new Error('publicKey must be 64 lowercase hex chars');
const url = validatePeerUrl(String(input.url));
const peers = readPeers(basePath);
if (peers.length >= MAX_PEERS) throw new Error(`peer registry is full (${MAX_PEERS})`);
const existing = peers.find(p => p.nodeId === input.nodeId);
if (existing) {
// Re-pinning a different key for a known nodeId is how a key-substitution
// attack would present. Require an explicit remove first.
if (existing.publicKey !== input.publicKey) {
throw new Error(`nodeId ${input.nodeId} is already pinned to a different publicKey; remove it first`);
}
existing.url = url;
if (input.label) existing.label = input.label;
writePeers(basePath, peers);
return existing;
}
const peer: FederationPeer = {
nodeId: input.nodeId,
url,
publicKey: input.publicKey,View on GitHub (pinned to 2602b642d9)