{"record":{"id":"c6581c70bf1dbc7c","repo":"ruvnet/ruflo","slug":"federationbridge-decode-expected-type-claim-even","errorCode":null,"errorMessage":"FederationBridge.decode: expected type 'claim-event', got '${envelope.type}'","messagePattern":"FederationBridge\\.decode: expected type 'claim-event', got '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/claims/src/infrastructure/federation-bridge.ts","lineNumber":147,"sourceCode":"        event,\n        vclock,\n        originNodeId: this.opts.nodeId,\n        hlc,\n      },\n    };\n\n    await this.opts.transport.publish(envelope);\n    return envelope;\n  }\n\n  /**\n   * Decode an incoming envelope back into the claim event + vclock + hlc\n   * tuple. Validates the envelope shape; does NOT verify the signature\n   * (that's the transport's job, before this method is called).\n   */\n  decode(envelope: FederationEnvelope): ClaimEventEnvelopePayload {\n    if (envelope.type !== CLAIM_EVENT_MESSAGE_TYPE) {\n      throw new Error(\n        `FederationBridge.decode: expected type '${CLAIM_EVENT_MESSAGE_TYPE}', got '${envelope.type}'`,\n      );\n    }\n    const payload = envelope.payload as ClaimEventEnvelopePayload;\n    if (!payload || typeof payload !== 'object') {\n      throw new Error('FederationBridge.decode: payload missing or non-object');\n    }\n    if (!payload.event || !payload.vclock || !payload.hlc || !payload.originNodeId) {\n      throw new Error('FederationBridge.decode: payload missing required fields');\n    }\n    return payload;\n  }\n}\n","sourceCodeStart":129,"sourceCodeEnd":161,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/claims/src/infrastructure/federation-bridge.ts#L129-L161","documentation":"FederationBridge.decode only accepts envelopes whose type equals the claim-event message type ('claim-event'). A transport that multiplexes several message types will hand the decoder foreign envelopes; decode throws on the type mismatch instead of mis-parsing the payload. Signature verification is deliberately out of scope — it happens in the transport before decode runs.","triggerScenarios":"Routing a heartbeat, handshake, or custom envelope into FederationBridge.decode; a peer publishing claim events under a renamed type string after a schema change; hand-built test envelopes using type: 'claim' or 'ClaimEvent'.","commonSituations":"Shared message bus/channel carrying multiple message types with no type dispatch; version skew between bridge implementations after a type rename; test fixtures constructing envelopes by hand.","solutions":["Dispatch on envelope.type before decoding: only call decode when the type matches the claim-event constant","Publish claim events on a dedicated topic/channel so foreign types cannot reach this decoder","After any type rename, align the CLAIM_EVENT_MESSAGE_TYPE constant across all nodes before deploying"],"exampleFix":"// before\nconst payload = bridge.decode(envelope); // throws on heartbeats\n\n// after\nif (envelope.type === 'claim-event') {\n  const payload = bridge.decode(envelope);\n} else {\n  handleOtherMessage(envelope);\n}","handlingStrategy":"type-guard","validationCode":"if (envelope.type !== 'claim-event') {\n  routeElsewhere(envelope); // heartbeat, handshake, custom types\n} else {\n  const payload = bridge.decode(envelope);\n}","typeGuard":"function isClaimEventEnvelope(e: FederationEnvelope): boolean {\n  return e.type === 'claim-event';\n}","tryCatchPattern":"try { payload = bridge.decode(envelope); }\ncatch (e) { if (e instanceof Error && e.message.includes(\"expected type 'claim-event'\")) { dropOrRoute(envelope); } else throw e; }","preventionTips":["Dispatch on message type at the transport boundary before any decoder sees the envelope","Use a dedicated topic/channel per message type","Bump and align type constants atomically across nodes during rolling upgrades"],"tags":["federation","protocol-validation","message-routing","typescript"],"backgroundTag":"message-type-mismatch","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}