ruvnet/ruflo · error · TypeError
Federation canonicalization rejects ${typeof value}
Error message
Federation canonicalization rejects ${typeof value} What it means
The JCS canonicalizer only handles JSON-representable values: bigint, function, symbol, and undefined all hit this rejection because they have no canonical JSON form and cannot participate in a deterministically signed payload. This is the explicit case list in the switch, distinct from the defensive default branch below it.
Source
Thrown at v3/@claude-flow/plugin-agent-federation/src/application/inbound-dispatcher.ts:162
switch (typeof value) {
case 'boolean':
return value ? 'true' : 'false';
case 'string':
return JSON.stringify(value);
case 'number':
if (!Number.isFinite(value) || Object.is(value, -0)) {
throw new TypeError('Federation canonicalization rejects non-canonical numbers');
}
if (Number.isInteger(value) && !Number.isSafeInteger(value)) {
throw new TypeError('Federation canonicalization rejects unsafe integers');
}
return JSON.stringify(value);
case 'bigint':
case 'function':
case 'symbol':
case 'undefined':
throw new TypeError(`Federation canonicalization rejects ${typeof value}`);
case 'object':
break;
default:
throw new TypeError(`Federation canonicalization rejects ${typeof value}`);
}
const object = value as object;
if (ancestors.has(object)) {
throw new TypeError('Federation canonicalization rejects cyclic values');
}
ancestors.add(object);
try {
if (Array.isArray(value)) {
const items: string[] = [];
for (let index = 0; index < value.length; index += 1) {
if (!Object.prototype.hasOwnProperty.call(value, index)) {
throw new TypeError('Federation canonicalization rejects sparse arrays');View on GitHub (pinned to fa13ee4ad6)
Solutions
- Omit undefined-valued keys instead of including them (build payloads via JSON round-trip or explicit deletion)
- Convert BigInt with String(value) before placing it in the envelope
- Ensure signed payloads originate from JSON.parse of received data or plain literals only
- Add a deep scan before signing that rejects bigint/function/symbol/undefined anywhere in the tree
Example fix
// before metadata.traceId = processBigintId(); // bigint // after metadata.traceId = String(processBigintId());
Defensive patterns
Strategy: type-guard
Validate before calling
// strip undefined keys and convert bigints before signing
function toSignable<T>(value: T): T {
return JSON.parse(
JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? String(v) : v)),
);
} Type guard
function isCanonicalValueKind(v: unknown): boolean {
const t = typeof v;
return (
t === 'string' ||
t === 'number' ||
t === 'boolean' ||
(t === 'object' && v !== null)
);
} Prevention
- Omit undefined-valued keys instead of including them
- Stringify BigInt at the boundary where it is created
- Build signed payloads from JSON.parse output or plain literals
- Spread-copy class instances into POJOs, not the instances themselves
When it happens
Trigger: BigInt IDs or counters stored in metadata (values from BigInt arithmetic); optional fields left as undefined instead of being omitted; property copies off class instances dragging function values along; Symbols used as enum-like keys with runtime values.
Common situations: Migrating numeric IDs to BigInt for range reasons; partial-object updates where absent fields stay undefined; objects built from class instances via spread.
Related errors
- Federation canonicalization rejects non-canonical numbers
- Federation canonicalization rejects unsafe integers
- Federation canonicalization rejects cyclic values
- Federation canonicalization rejects sparse arrays
- Federation canonicalization accepts only plain objects
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/061ba6a5afc2eb80.
Report an issue: GitHub.