{"record":{"id":"f6e59a6df07ed380","repo":"ruvnet/ruflo","slug":"roomid-is-required","errorCode":null,"errorMessage":"roomId is required","messagePattern":"roomId is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/mcp-tools/agentbbs-tools.ts","lineNumber":109,"sourceCode":"    ? input\n    : '.agentbbs';\n  if (/\\.\\.[\\\\/]|\\0/.test(p)) throw new Error('basePath contains disallowed characters');\n  const abs = isAbsolute(p) ? p : resolve(getProjectCwd(), p);\n  return abs;\n}\n\nfunction validateRoomLabel(label: string): string {\n  if (!label || typeof label !== 'string') throw new Error('roomLabel is required');\n  if (label.length > 128) throw new Error('roomLabel exceeds 128 chars');\n  // Rooms are conventionally `#sales`, `#finance`, etc. — keep `#` in the allow-list.\n  if (!/^[A-Za-z0-9_.\\-:/@#]+$/.test(label)) {\n    throw new Error('roomLabel may only contain [A-Za-z0-9_.\\\\-:/@#]');\n  }\n  return label;\n}\n\nfunction validateRoomId(roomId: string): string {\n  if (!roomId || typeof roomId !== 'string') throw new Error('roomId is required');\n  if (roomId.length > 128) throw new Error('roomId exceeds 128 chars');\n  if (!/^[A-Za-z0-9_.\\-:/@#]+$/.test(roomId)) {\n    throw new Error('roomId may only contain [A-Za-z0-9_.\\\\-:/@#]');\n  }\n  return roomId;\n}\n\nfunction ensureDir(dir: string): void {\n  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\nfunction roomIdFromLabel(label: string): string {\n  // Stable, deterministic roomId — strip leading `#`, lowercase, and append a\n  // short hash so we don't collide across two rooms with the same canonical\n  // label but different policies. Phase 1: deterministic over (label).\n  const norm = label.replace(/^#/, '').toLowerCase();\n  const h = createHash('sha256').update(`agentbbs:room:${norm}`).digest('hex').slice(0, 8);\n  return `${norm}-${h}`;","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/ruvnet/ruflo/blob/9c61c86f06b439af2a95085ae9bb0ca839662e41/v3/@claude-flow/cli/src/mcp-tools/agentbbs-tools.ts#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before — posting without capturing the id\nawait callMCPTool('agentbbs_post', { msgType: 'chat', payload: {...} });\n\n// after — resolve room first, then post\nconst room = await callMCPTool('agentbbs_create_room', { roomLabel: '#ops' });\nawait callMCPTool('agentbbs_post', { roomId: room.roomId, msgType: 'chat', payload: {...} });","handlingStrategy":"validation","validationCode":"function requireRoomId(id: unknown): string {\n  if (typeof id !== 'string' || id.length === 0) {\n    throw new Error('roomId is required — use the id returned by the create/resolve call');\n  }\n  return id;\n}","typeGuard":"const isRoomId = (v: unknown): v is string => typeof v === 'string' && v.length > 0;","tryCatchPattern":null,"preventionTips":["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"],"tags":["validation","agentbbs","required-parameter","rooms"],"backgroundTag":"missing-required-argument","analyzedSha":"9c61c86f06b439af2a95085ae9bb0ca839662e41","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}