ruvnet/ruflo · error · Error

message content is not canonical JSON

Error message

message content is not canonical JSON

What it means

Thrown when message content fails canonical JSON validation. Defense: serialize content with the canonical JSON serializer (sorted keys, no undefined, no lone surrogates) before computing digests or posting.

Source

Thrown at v3/@claude-flow/codex/src/harness/in-memory-inbox-reference.ts:75

    record: InMemoryInboxRecord;
  }>();
  private readonly quarantined: InMemoryQuarantinedMessage[] = [];
  private nextCursor = 1n;

  constructor(private readonly now: () => number = Date.now) {}

  send(message: HarnessMessage): MessageReceipt {
    if (!message.messageId.trim() || !message.issuer.trim() || !message.audience.trim()) {
      throw new Error('message ID, issuer, and audience are required');
    }
    const identity = inMemoryInboxIdentityKey(message.issuer, message.messageId);
    const receivedAt = new Date(this.now()).toISOString();
    let suppliedDigest: string;
    try {
      suppliedDigest = harnessMessageContentDigest(message.content);
    } catch {
      this.quarantine(message, 'content-digest-mismatch', receivedAt);
      throw new Error('message content is not canonical JSON');
    }
    if (suppliedDigest !== message.contentDigest) {
      this.quarantine(message, 'content-digest-mismatch', receivedAt);
      throw new Error('message contentDigest does not match canonical content');
    }
    try {
      parseCanonicalUnsigned(message.sequence, 'message sequence');
    } catch {
      throw new Error('message sequence must be a canonical unsigned decimal integer');
    }
    if (message.expiresAt !== undefined && !Number.isFinite(Date.parse(message.expiresAt))) {
      throw new Error('message expiresAt must be an ISO timestamp');
    }

    const envelopeDigest = sha256(canonicalJson(message));
    const prior = this.byIdentity.get(identity);
    if (prior) {
      if (prior.issuer !== message.issuer || prior.messageId !== message.messageId) {

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Serialize message content with the canonical JSON serializer (sorted keys, no undefined, NFC strings) instead of JSON.stringify on arbitrary input.
  2. Strip unsupported values (undefined, functions, symbols, cycles) from the content before posting.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at v3/@claude-flow/codex/src/harness/in-memory-inbox-reference.ts:75 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/a5d22fba1d62bffe. Report an issue: GitHub.