ruvnet/ruflo · error
FederationBridge.decode: payload missing or non-object
Error message
FederationBridge.decode: payload missing or non-object
What it means
After the type check passes, decode requires envelope.payload to be a non-null object. A null, undefined, string, or number payload means the envelope itself is malformed — publisher bug, truncated transport message, or schema drift — and decode refuses to cast it to ClaimEventEnvelopePayload.
Source
Thrown at v3/@claude-flow/claims/src/infrastructure/federation-bridge.ts:153
await this.opts.transport.publish(envelope);
return envelope;
}
/**
* Decode an incoming envelope back into the claim event + vclock + hlc
* tuple. Validates the envelope shape; does NOT verify the signature
* (that's the transport's job, before this method is called).
*/
decode(envelope: FederationEnvelope): ClaimEventEnvelopePayload {
if (envelope.type !== CLAIM_EVENT_MESSAGE_TYPE) {
throw new Error(
`FederationBridge.decode: expected type '${CLAIM_EVENT_MESSAGE_TYPE}', got '${envelope.type}'`,
);
}
const payload = envelope.payload as ClaimEventEnvelopePayload;
if (!payload || typeof payload !== 'object') {
throw new Error('FederationBridge.decode: payload missing or non-object');
}
if (!payload.event || !payload.vclock || !payload.hlc || !payload.originNodeId) {
throw new Error('FederationBridge.decode: payload missing required fields');
}
return payload;
}
}
View on GitHub (pinned to fa13ee4ad6)
Solutions
- Validate inbound envelopes at the transport boundary (payload must be an object) and quarantine rejects there with context
- Always build outbound envelopes via the bridge's encode() rather than hand-assembling them
- Add a schema check (e.g. zod) on the wire format before decode so failures carry the offending envelope
Example fix
// before
const payload = bridge.decode(envelope);
// after
if (typeof envelope.payload !== 'object' || envelope.payload === null) {
throw new Error(`malformed envelope from ${envelope.sourceNodeId}: payload missing`);
}
const payload = bridge.decode(envelope); Defensive patterns
Strategy: type-guard
Validate before calling
const ok = typeof envelope.payload === 'object' && envelope.payload !== null;
if (!ok) { quarantine(envelope); } else { const payload = bridge.decode(envelope); } Type guard
function hasObjectPayload(e: FederationEnvelope): boolean {
return typeof e.payload === 'object' && e.payload !== null;
} Try / catch
try { payload = bridge.decode(envelope); }
catch (e) { if (e instanceof Error && e.message.includes('payload missing or non-object')) { quarantine(envelope); } else throw e; } Prevention
- Build outbound envelopes exclusively with encode()
- Schema-check inbound envelopes at the transport and reject before decode
- Include envelope IDs in quarantine logs to trace the misbehaving publisher
When it happens
Trigger: A publisher sends an envelope with payload omitted or set to a scalar; a JSON transport drops the field; a test constructs FederationEnvelope with only { type }.
Common situations: Partial envelope construction in unit tests; a renamed payload field after a protocol change; deserializers that skip missing keys and hand decode an incomplete object.
Related errors
- FederationBridge.decode: expected type 'claim-event', got '$
- FederationBridge.decode: payload missing required fields
- Concurrent write detected on aggregate '${aggregateId}'. Res
- HLC skew exceeded: received physicalMs=${receivedPhysicalMs}
- Unsupported federation signature mode: ${String(signatureMod
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/358151e0d631b48d.
Report an issue: GitHub.