ruvnet/ruflo · error · Error
roomId is required
Error message
roomId is required
What it means
validateRoomId() requires a non-empty string roomId for agentbbs operations that address an existing room (unlike roomLabel, which names a room at creation). Empty, missing, or non-string values throw immediately. roomId is the stable identifier that roomIdFromLabel() derives (canonical label + short hash) or that a previous call returned.
Solutions
- Pass the roomId string exactly as returned by the create/resolve call (validateRoomId accepts the same charset as labels)
- Check the room-creation step succeeded and returned an id before posting to it
- Verify the key is 'roomId' (camelCase) and is a string, not a number or object
Example fix
// before — posting without capturing the id
await callMCPTool('agentbbs_post', { msgType: 'chat', payload: {...} });
// after — resolve room first, then post
const room = await callMCPTool('agentbbs_create_room', { roomLabel: '#ops' });
await callMCPTool('agentbbs_post', { roomId: room.roomId, msgType: 'chat', payload: {...} }); Defensive patterns
Strategy: validation
Validate before calling
function requireRoomId(id: unknown): string {
if (typeof id !== 'string' || id.length === 0) {
throw new Error('roomId is required — use the id returned by the create/resolve call');
}
return id;
} Type guard
const isRoomId = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Prevention
- Always capture and reuse the roomId returned by create/resolve — never fabricate one
- Check the create step succeeded before chaining a post/read
- Keep roomLabel (name at creation) and roomId (stable address) distinct in your data model
When it happens
Trigger: Posting/reading in a room while the roomId field was dropped from the payload; passing a numeric DB id instead of the string roomId; using the output of a failed room-create call that never returned an id.
Common situations: Chaining tool calls where the first step's failure isn't checked, so its undefined result is forwarded as roomId; renaming confusion between roomLabel and roomId parameters; typed languages coercing id types.
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
- roomLabel is required
- msgType is required
- roomId exceeds 128 chars
- roomId may only contain [A-Za-z0-9_.\\-:/@#]
- roomLabel exceeds 128 chars
AI-assisted analysis of ruvnet/ruflo@9c61c86f06 (2026-08-18).
Data as JSON: /api/errors/f6e59a6df07ed380.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/mcp-tools/agentbbs-tools.ts:109
? input
: '.agentbbs';
if (/\.\.[\\/]|\0/.test(p)) throw new Error('basePath contains disallowed characters');
const abs = isAbsolute(p) ? p : resolve(getProjectCwd(), p);
return abs;
}
function validateRoomLabel(label: string): string {
if (!label || typeof label !== 'string') throw new Error('roomLabel is required');
if (label.length > 128) throw new Error('roomLabel exceeds 128 chars');
// Rooms are conventionally `#sales`, `#finance`, etc. — keep `#` in the allow-list.
if (!/^[A-Za-z0-9_.\-:/@#]+$/.test(label)) {
throw new Error('roomLabel may only contain [A-Za-z0-9_.\\-:/@#]');
}
return label;
}
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');
if (!/^[A-Za-z0-9_.\-:/@#]+$/.test(roomId)) {
throw new Error('roomId may only contain [A-Za-z0-9_.\\-:/@#]');
}
return roomId;
}
function ensureDir(dir: string): void {
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
}
function roomIdFromLabel(label: string): string {
// Stable, deterministic roomId — strip leading `#`, lowercase, and append a
// short hash so we don't collide across two rooms with the same canonical
// label but different policies. Phase 1: deterministic over (label).
const norm = label.replace(/^#/, '').toLowerCase();
const h = createHash('sha256').update(`agentbbs:room:${norm}`).digest('hex').slice(0, 8);
return `${norm}-${h}`;View on GitHub (pinned to 9c61c86f06)