ruvnet/ruflo · error · Error

msgType is required

Error message

msgType is required

What it means

Thrown by the federation_bbs_publish handler when msgType coerces to an empty string (input.msgType is undefined, null, '', or missing). msgType is the typed event kind that the cockpit and other pods dispatch on (pod-status / task-result / alert / human-override-ack / bench-result), so an empty value is rejected before envelope construction.

Source

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

          type: 'string',
          description: 'Typed event kind (pod-status / task-result / alert / human-override-ack / bench-result).',
        },
        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,

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Always supply msgType as one of the documented kinds (e.g. 'pod-status').
  2. Validate at your boundary that msgType is a non-empty string before invoking the tool.
  3. If msgType is dynamic, restrict it to a known enum in your caller.

Example fix

// before
federation_bbs_publish({ roomId, payload }); // throws: msgType is required
// after
federation_bbs_publish({ roomId, msgType: 'alert', payload });
Defensive patterns

Strategy: validation

Validate before calling

const MSG_TYPES = new Set(['pod-status','task-result','alert','human-override-ack','bench-result']);
function requireMsgType(t: unknown): string {
  if (typeof t !== 'string' || t.length === 0) throw new Error('msgType required');
  return t;
}

Type guard

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

Try / catch

null

Prevention

When it happens

Trigger: Calling federation_bbs_publish without msgType; passing an empty string; passing a value whose String() coercion is empty; field name typo (`type` instead of `msgType`).

Common situations: Event pipeline that conditionally sets msgType and hit the missing branch; schema mismatch between producer and the tool's expected field; a fixture copied without the msgType line.

Related errors


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