ruvnet/ruflo · error
FederationBridge.decode: payload missing required fields
Error message
FederationBridge.decode: payload missing required fields
What it means
decode requires all four payload fields — event, vclock, hlc, and originNodeId — to be present; missing any one throws. These carry the domain event, causal history, and origin identity, so a partial payload cannot be reconstructed into a federated claim event.
Source
Thrown at v3/@claude-flow/claims/src/infrastructure/federation-bridge.ts:156
}
/**
* 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
- Publish only via encode(), which emits the full field set
- Pin all federated nodes to a bridge version that emits event/vclock/hlc/originNodeId before admitting new traffic
- Log the rejected envelope with its missing keys to identify the misbehaving producer quickly
Example fix
// before
const payload = bridge.decode(envelope);
// after
const p = envelope.payload as Record<string, unknown>;
for (const k of ['event', 'vclock', 'hlc', 'originNodeId']) {
if (!p?.[k]) throw new Error(`envelope missing ${k}`);
}
const payload = bridge.decode(envelope); Defensive patterns
Strategy: type-guard
Validate before calling
const p = envelope.payload as Record<string, unknown> | undefined;
const complete = !!p && !!p.event && !!p.vclock && !!p.hlc && !!p.originNodeId;
if (!complete) { reject(envelope); } else { const payload = bridge.decode(envelope); } Type guard
function isClaimEventPayload(p: unknown): p is ClaimEventEnvelopePayload {
if (typeof p !== 'object' || p === null) return false;
const o = p as Record<string, unknown>;
return !!o.event && !!o.vclock && !!o.hlc && !!o.originNodeId;
} Try / catch
try { payload = bridge.decode(envelope); }
catch (e) { if (e instanceof Error && e.message.includes('missing required fields')) { rejectWithDetail(envelope); } else throw e; } Prevention
- Never hand-assemble payloads; use encode() which always emits all four fields
- Version gate federation peers: refuse mixed-version traffic during rolling upgrades
- Log which field is missing to pinpoint the producer immediately
When it happens
Trigger: A peer running an older bridge version that omits a field (commonly originNodeId); hand-serialized payloads; JSON round-trips that drop undefined keys; payloads built with object spread where some keys are undefined.
Common situations: Rolling upgrades with mixed node versions; abbreviated test fixtures; a producer that conditionally sets fields depending on message content.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- FederationBridge.decode: expected type 'claim-event', got '$
- FederationBridge.decode: payload missing or non-object
- 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/590e32f5b9628c1d.
Report an issue: GitHub.