ruvnet/ruflo · error · TypeError

JCS canonicalization rejects undefined object values

Error message

JCS canonicalization rejects undefined object values

What it means

JCS canonicalizer guard: while serializing a plain object, a key's value is undefined. JSON.stringify would silently drop such members, which would make the canonical (signed) form diverge from the in-memory data, so the object is rejected as non-JSON-compatible.

Source

Thrown at v3/@claude-flow/security/src/policy/product-plane.ts:1118

  }
  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')}`;
}

export interface SignedProductActionEnvelopeV1 {
  envelope: ProductActionEnvelopeV1;
  algorithm: 'Ed25519';
  keyId: string;

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Remove keys whose value is undefined before canonicalizing, or replace them with null.
  2. Filter the object: Object.fromEntries(Object.entries(obj).filter(([,v]) => v !== undefined)).
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at v3/@claude-flow/security/src/policy/product-plane.ts:1118 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/8c9174736dce0461. Report an issue: GitHub.