ruvnet/ruflo · error · Error

msgType must be alnum + _ - and ≤64 chars

Error message

msgType must be alnum + _ - and ≤64 chars

What it means

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.

Source

Thrown at v3/@claude-flow/cli/src/mcp-tools/agentbbs-tools.ts:277

        },
        payload: {
          type: 'object',
          description: 'Event-specific JSON-serializable payload.',
        },
        signature: {
          type: 'string',
          description: 'Optional Ed25519 signature over the canonical envelope bytes. Phase 1: pass-through.',
        },
      },
      required: ['roomId', 'msgType', 'payload'],
    },
    handler: async (input) => {
      const basePath = resolveBasePath(input.basePath as string | undefined);
      const roomId = validateRoomId(String(input.roomId));
      const msgType = String(input.msgType ?? '');
      if (!msgType) throw new Error('msgType is required');
      if (msgType.length > 64 || !/^[A-Za-z0-9_-]+$/.test(msgType)) {
        throw new Error('msgType must be alnum + _ - and ≤64 chars');
      }
      if (typeof input.payload !== 'object' || input.payload === null) {
        throw new Error('payload must be a JSON object');
      }

      const api = await loadAgentbbs();
      if (!api) return degradedResult('agentbbs-not-found');

      ensureDir(basePath);
      const logPath = roomLogPath(basePath, roomId);
      const env: BbsEnvelope = {
        envelopeId: base64url(randomBytes(12)),
        roomId,
        seq: nextSeq(logPath),
        msgType,
        payload: input.payload,
        timestamp: new Date().toISOString(),
        signature: input.signature ? String(input.signature) : undefined,

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Use short, kebab-style identifiers from the documented set: pod-status, task-result, alert, human-override-ack, bench-result.
  2. If you need scoping, flatten with `-` or `_` rather than `/` or `:`.
  3. Truncate or hash long dynamic types to ≤64 chars before publish.

Example fix

// before
federation_bbs_publish({ roomId, msgType: 'pod/status:critical', payload });
// after
federation_bbs_publish({ roomId, msgType: 'pod-status', payload });
Defensive patterns

Strategy: validation

Validate before calling

const MSG_TYPE_RE = /^[A-Za-z0-9_-]+$/;
function normalizeMsgType(t: string): string {
  const v = t.replace(/[:\/#]/g, '-').slice(0, 64);
  if (!MSG_TYPE_RE.test(v)) throw new Error('msgType cannot be normalized to allowed set');
  return v;
}

Type guard

const isMsgType = (v: string): boolean => v.length > 0 && v.length <= 64 && /^[A-Za-z0-9_-]+$/.test(v);

Try / catch

null

Prevention

When it happens

Trigger: 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.

Common situations: 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 '/'.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/46404fac50427b14. Report an issue: GitHub.