{"record":{"id":"5b69eb124709668e","repo":"ruvnet/ruflo","slug":"unsupported-federation-signature-version-string","errorCode":null,"errorMessage":"Unsupported federation signature version: ${String(version)}","messagePattern":"Unsupported federation signature version: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/plugin-agent-federation/src/application/inbound-dispatcher.ts","lineNumber":206,"sourceCode":"    if (prototype !== Object.prototype && prototype !== null) {\n      throw new TypeError('Federation canonicalization accepts only plain objects');\n    }\n\n    const record = value as Record<string, unknown>;\n    const entries = Object.keys(record)\n      .sort()\n      .map((key) => `${JSON.stringify(key)}:${canonicalizeJcsValue(record[key], ancestors)}`);\n    return `{${entries.join(',')}}`;\n  } finally {\n    ancestors.delete(object);\n  }\n}\n\nfunction envelopeSignatureVersion(message: AgentMessage): EnvelopeSignatureVersion {\n  const version = (message.metadata as Record<string, unknown> | undefined)?.signatureVersion;\n  if (version === undefined) return 'legacy-v1';\n  if (version === 'jcs-v1') return version;\n  throw new TypeError(`Unsupported federation signature version: ${String(version)}`);\n}\n\nexport function selectEnvelopeSignatureVersion(\n  mode: EnvelopeSignatureMode,\n  peerProtocols: readonly string[],\n  messageType?: string,\n): EnvelopeSignatureVersion {\n  const selected = mode === 'legacy'\n    ? 'legacy-v1'\n    : peerProtocols.includes(JCS_SIGNATURE_PROTOCOL)\n      ? 'jcs-v1'\n      : mode === 'prefer-jcs'\n        ? 'legacy-v1'\n        : null;\n  if (selected === null) {\n    throw new Error('PEER_SIGNATURE_PROTOCOL_UNSUPPORTED');\n  }\n  if (","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/plugin-agent-federation/src/application/inbound-dispatcher.ts#L188-L224","documentation":"envelopeSignatureVersion() reads message.metadata.signatureVersion: absent means 'legacy-v1', the exact string 'jcs-v1' is accepted, and anything else — numbers, booleans, or strings like 'jcs-v2' — throws a TypeError. Inbound envelopes with an unknown signature version cannot be verified, so they are rejected before any signature check rather than mis-verified under an assumed scheme.","triggerScenarios":"A peer running a newer release advertising 'jcs-v2'; a hand-crafted or tampered envelope with signatureVersion set to a non-string; another metadata field accidentally leaking into signatureVersion during envelope construction.","commonSituations":"Version skew across federation peers after a partial upgrade; adversarial probing with malformed envelopes; envelope builders copying whole metadata objects from unknown sources.","solutions":["Upgrade both peers so the negotiated scheme agrees (see selectEnvelopeSignatureVersion and the peer's advertised protocols)","Treat inbound messages with unknown signatureVersion as untrusted: drop and log, do not retry","If you build envelopes manually, set metadata.signatureVersion only to 'jcs-v1' or omit it entirely","Reject non-string signatureVersion at your ingress before it reaches the dispatcher"],"exampleFix":"// before\nenvelope.metadata.signatureVersion = 'jcs-v2';\n// after\nenvelope.metadata.signatureVersion = 'jcs-v1'; // or omit the key for legacy-v1","handlingStrategy":"type-guard","validationCode":"// at ingress: only accept known signature versions before dispatch\nconst sv = (msg.metadata as Record<string, unknown>)?.signatureVersion;\nif (sv !== undefined && sv !== 'jcs-v1') {\n  // untrusted envelope: drop and log, do not hand to the dispatcher\n  log.warn('dropping envelope with unknown signatureVersion', sv);\n  continue;\n}","typeGuard":"type EnvelopeSignatureVersion = 'legacy-v1' | 'jcs-v1';\nfunction isKnownSignatureVersion(v: unknown): v is EnvelopeSignatureVersion {\n  return v === undefined || v === 'jcs-v1';\n}","tryCatchPattern":"try {\n  dispatcher.dispatch(msg);\n} catch (e) {\n  if (String(e).includes('Unsupported federation signature version')) {\n    // version skew or tampering: quarantine the message, alert, do not retry\n    quarantine(msg);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Negotiate the scheme via selectEnvelopeSignatureVersion against the peer's advertised protocols","Upgrade federation peers together to avoid version skew","Set metadata.signatureVersion only to 'jcs-v1' or omit it entirely","Treat unknown signature versions as untrusted input, never retry them"],"tags":["canonicalization","signing","versioning","protocol"],"backgroundTag":"unsupported-protocol-version","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}