{"record":{"id":"46404fac50427b14","repo":"ruvnet/ruflo","slug":"msgtype-must-be-alnum-and-64-chars","errorCode":null,"errorMessage":"msgType must be alnum + _ - and ≤64 chars","messagePattern":"msgType must be alnum \\+ _ - and ≤64 chars","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/mcp-tools/agentbbs-tools.ts","lineNumber":277,"sourceCode":"        },\n        payload: {\n          type: 'object',\n          description: 'Event-specific JSON-serializable payload.',\n        },\n        signature: {\n          type: 'string',\n          description: 'Optional Ed25519 signature over the canonical envelope bytes. Phase 1: pass-through.',\n        },\n      },\n      required: ['roomId', 'msgType', 'payload'],\n    },\n    handler: async (input) => {\n      const basePath = resolveBasePath(input.basePath as string | undefined);\n      const roomId = validateRoomId(String(input.roomId));\n      const msgType = String(input.msgType ?? '');\n      if (!msgType) throw new Error('msgType is required');\n      if (msgType.length > 64 || !/^[A-Za-z0-9_-]+$/.test(msgType)) {\n        throw new Error('msgType must be alnum + _ - and ≤64 chars');\n      }\n      if (typeof input.payload !== 'object' || input.payload === null) {\n        throw new Error('payload must be a JSON object');\n      }\n\n      const api = await loadAgentbbs();\n      if (!api) return degradedResult('agentbbs-not-found');\n\n      ensureDir(basePath);\n      const logPath = roomLogPath(basePath, roomId);\n      const env: BbsEnvelope = {\n        envelopeId: base64url(randomBytes(12)),\n        roomId,\n        seq: nextSeq(logPath),\n        msgType,\n        payload: input.payload,\n        timestamp: new Date().toISOString(),\n        signature: input.signature ? String(input.signature) : undefined,","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/mcp-tools/agentbbs-tools.ts#L259-L295","documentation":"Thrown by the federation_bbs_publish handler when msgType is present but either longer than 64 characters or fails the strict regex `/^[A-Za-z0-9_-]+$/`. The format is tighter than roomLabel/roomId because msgType is used as a dispatch key and stored in every envelope header — no scoping punctuation (`:`, `/`, `#`) is permitted.","triggerScenarios":"msgType contains a space, slash, colon, or `#` (e.g. 'pod/status'); a free-form string longer than 64 chars; unicode or shell metacharacters; a copy of the human label accidentally used as msgType.","commonSituations":"Producer reused a display name as the type; a versioned string like 'pod-status-v2-beta-3-...' exceeded 64 chars; integration that joins segments with '/'.","solutions":["Use short, kebab-style identifiers from the documented set: pod-status, task-result, alert, human-override-ack, bench-result.","If you need scoping, flatten with `-` or `_` rather than `/` or `:`.","Truncate or hash long dynamic types to ≤64 chars before publish."],"exampleFix":"// before\nfederation_bbs_publish({ roomId, msgType: 'pod/status:critical', payload });\n// after\nfederation_bbs_publish({ roomId, msgType: 'pod-status', payload });","handlingStrategy":"validation","validationCode":"const MSG_TYPE_RE = /^[A-Za-z0-9_-]+$/;\nfunction normalizeMsgType(t: string): string {\n  const v = t.replace(/[:\\/#]/g, '-').slice(0, 64);\n  if (!MSG_TYPE_RE.test(v)) throw new Error('msgType cannot be normalized to allowed set');\n  return v;\n}","typeGuard":"const isMsgType = (v: string): boolean => v.length > 0 && v.length <= 64 && /^[A-Za-z0-9_-]+$/.test(v);","tryCatchPattern":"null","preventionTips":["Avoid scoping punctuation in msgType — use `-` to join segments.","Cap dynamic types at 64 chars (hash/truncate) before publish.","Keep a documented enum so producers do not invent ad-hoc strings."],"tags":["validation","agentbbs","federation","format"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}