ruvnet/ruflo · error · TypeError
JCS canonicalization accepts only JSON-compatible plain obje
Error message
JCS canonicalization accepts only JSON-compatible plain objects
What it means
JCS canonicalizer guard: the value being serialized is neither a primitive nor an array nor a plain object (isRecord failed) — e.g. a Date, Map, class instance, or null-prototype object. JCS only defines canonical forms for JSON-compatible plain objects, so such values are rejected rather than coerced.
Source
Thrown at v3/@claude-flow/security/src/policy/product-plane.ts:1112
assertUnicodeScalarString(value);
return JSON.stringify(value);
}
if (typeof value === 'number') {
if (!Number.isFinite(value)) throw new TypeError('JCS canonicalization rejects non-finite numbers');
return JSON.stringify(value);
}
if (Array.isArray(value)) {
const items: string[] = [];
for (let index = 0; index < value.length; index++) {
if (!Object.prototype.hasOwnProperty.call(value, index)) {
throw new TypeError('JCS canonicalization rejects sparse arrays');
}
items.push(canonicalizeProductPlane(value[index]));
}
return `[${items.join(',')}]`;
}
if (!isRecord(value)) {
throw new TypeError('JCS canonicalization accepts only JSON-compatible plain objects');
}
const entries: string[] = [];
for (const key of Object.keys(value).sort()) {
assertUnicodeScalarString(key);
if (value[key] === undefined) {
throw new TypeError('JCS canonicalization rejects undefined object values');
}
entries.push(`${JSON.stringify(key)}:${canonicalizeProductPlane(value[key])}`);
}
return `{${entries.join(',')}}`;
}
export function canonicalProductPlaneBytes(value: unknown): Uint8Array {
return Buffer.from(canonicalizeProductPlane(value), 'utf8');
}
export function canonicalProductPlaneDigest(value: unknown): `sha256:${string}` {
return `sha256:${createHash('sha256').update(canonicalProductPlaneBytes(value)).digest('hex')}`;View on GitHub (pinned to fa13ee4ad6)
Solutions
- Strip class instances, Maps, Sets, and functions before canonicalizing; convert them to plain JSON objects first.
- Use a serializer (e.g. JSON.parse(JSON.stringify(value)) with a replacer) to normalize non-plain objects into JSON-compatible shapes.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at v3/@claude-flow/security/src/policy/product-plane.ts:1112 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/9228656f0f59eda2.
Report an issue: GitHub.