ruvnet/ruflo · error
roomId is required
Error message
roomId is required
What it means
validateRoomId() requires a non-empty string roomId before any room-scoped federation operation proceeds. A missing, null, undefined, or empty roomId cannot identify a room on disk, so the library fails fast. This is the first of several checks (length, charset, traversal) applied to room identifiers.
Solutions
- Check the caller and ensure a non-empty roomId is passed (default it or reject the request earlier).
- Validate/skip envelopes without roomId before merging: if (!env.roomId) continue.
- At API boundaries, return a 400 to clients that omit roomId instead of letting it reach the sync layer.
- Add a runtime check at the entry point that produces the call so the failure surfaces where the data originates.
Example fix
// before
syncRoomFromPeer(base, peer, envelope.roomId); // throws when missing
// after
if (!envelope.roomId) { log.warn('envelope missing roomId'); return; }
syncRoomFromPeer(base, peer, envelope.roomId); Defensive patterns
Strategy: validation
Validate before calling
function hasRoomId(v) { return typeof v === 'string' && v.length > 0; }
if (!hasRoomId(envelope.roomId)) throw new Error('roomId is required'); Type guard
const hasRoomId = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Try / catch
try {
syncRoomFromPeer(basePath, peer, roomId);
} catch (e) {
if (e.message === 'roomId is required') {
log.warn('skipping envelope without roomId');
return;
}
throw e;
} Prevention
- Validate envelope shape (including roomId) at ingest before merging
- Reject requests missing roomId at the API boundary with a 400
- Make roomId a required, non-optional field in your envelope type/serializer
- Fail fast where the data originates, not deep in the sync layer
When it happens
Trigger: Calling mergeEnvelopes, syncRoomFromPeer, or a server handler with roomId === '' , null, or undefined — e.g. an envelope JSON parsed from a peer line lacking a roomId field, or a request handler that never extracted the room from the URL/body.
Common situations: Malformed envelopes from a remote peer missing the roomId field; frontend sending an empty room query param; refactored code path dropping the roomId argument; a sync job iterating records where roomId is optional.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- roomId exceeds 128 chars
- Invalid item ID
- Invalid worker type
- publicKey must be 64 lowercase hex chars
- Rating must be integer 1-5
AI-assisted analysis of ruvnet/ruflo@2602b642d9 (2026-09-15).
Data as JSON: /api/errors/5f23b50541d140db.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/mcp-tools/agentbbs-federation.ts:317
const next = peers.filter(p => p.nodeId !== nodeId);
if (next.length === peers.length) return false;
writePeers(basePath, next);
return true;
}
export function readEnvelopes(basePath: string, roomId: string): SignedEnvelope[] {
const p = roomLogPath(basePath, roomId);
if (!existsSync(p)) return [];
const out: SignedEnvelope[] = [];
for (const line of readFileSync(p, 'utf-8').split(/\r?\n/)) {
if (!line.trim()) continue;
try { out.push(JSON.parse(line)); } catch { /* skip malformed */ }
}
return out;
}
export function validateRoomId(roomId: string): string {
if (!roomId || typeof roomId !== 'string') throw new Error('roomId is required');
if (roomId.length > 128) throw new Error('roomId exceeds 128 chars');
// Also blocks path traversal: `.` is allowed but `/` segments cannot form
// `..` without tripping the explicit check below.
if (!ROOM_ID_RE.test(roomId)) throw new Error('roomId has invalid characters');
if (roomId.includes('..')) throw new Error('roomId must not contain ..');
return roomId;
}
export interface MergeResult {
merged: number;
skippedDuplicate: number;
skippedUnverified: number;
skippedOversize: number;
skippedHopLimit: number;
}
/**
* Union-merge verified envelopes from a peer into the local room log.View on GitHub (pinned to 2602b642d9)