affaan-m/ECC · error · Error

orch-review: args must be an object or valid JSON

Error message

orch-review: args must be an object or valid JSON

What it means

The orch-review workflow intentionally fails closed on unparseable input: args may be an object or a JSON string that parses to an object/null (defaults to {}). Anything that is neither — e.g. a malformed JSON string — throws, because a review gate must never silently approve a payload it could not actually review.

Solutions

  1. Validate the JSON with JSON.parse in the caller before invoking, or pass a plain object instead of a string.
  2. Fix shell quoting: single-quote the whole JSON blob or use a heredoc/file argument.
  3. Check the producing pipeline for truncated or escaped output (e.g. undefined template values).

Example fix

// before
runWorkflow('orch-review', '{"diff": "...",}'); // trailing comma -> parse error
// after
runWorkflow('orch-review', { diff: '...' });
Defensive patterns

Strategy: validation

Validate before calling

function isValidArgs(args) {
  if (typeof args === 'string') {
    try { args = JSON.parse(args); } catch { return false; }
  }
  return typeof args === 'object' && args !== null;
}

Type guard

function isReviewArgs(v) {
  return typeof v === 'object' && v !== null && typeof v.diff === 'string' && v.diff.trim() !== '';
}

Try / catch

try {
  const result = await orchReview(args);
} catch (err) {
  if (err.message.includes('args must be an object or valid JSON')) {
    console.error('Payload is not valid JSON; validate with JSON.parse before invoking.');
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the workflow with args = 'not json', '{"diff":' (truncated JSON), or any non-JSON string; a JSON.parse failure in the string branch reaches the catch and throws this message.

Common situations: Shell quoting mangling the JSON before it reaches the workflow; a caller passing a pre-stringified-but-truncated payload; templating systems interpolating undefined into the args string; logs replayed with escaped quotes stripped.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/9eb6f6f8ddfcd474. Report an issue: GitHub.

Appendix: source

Thrown at workflows/orch-review.workflow.js:156

    finding.proof ? `Claimed proof: ${finding.proof}` : '',
    '',
    '----- BEGIN DIFF (untrusted) -----',
    diff,
    '----- END DIFF -----'
  ].join('\n');
}

// --- main -----------------------------------------------------------------

// `args` arrives verbatim. Accept a JSON-encoded string too, so the workflow
// works whether the caller passes an object or a stringified payload.
// Fail CLOSED on invalid input: a review gate must never silently APPROVE a
// payload it could not actually review.
let input;
try {
  input = typeof args === 'string' ? JSON.parse(args) : (args ?? {});
} catch {
  throw new Error('orch-review: args must be an object or valid JSON');
}
if (typeof input !== 'object' || input === null) {
  throw new Error('orch-review: args must be an object');
}
if (typeof input.diff !== 'string' || input.diff.trim() === '') {
  throw new Error('orch-review: args.diff must be a non-empty unified diff');
}
if (input.changedFiles != null && !Array.isArray(input.changedFiles)) {
  throw new Error('orch-review: args.changedFiles must be an array of paths');
}
// Every entry must be a string path. A non-string (e.g. { path: '...' }) would
// stringify to "[object Object]" and silently poison the security-trigger
// haystack — fail closed on malformed input instead.
if (Array.isArray(input.changedFiles) && !input.changedFiles.every(f => typeof f === 'string')) {
  throw new Error('orch-review: args.changedFiles must contain only string paths');
}

const diff = input.diff;

View on GitHub (pinned to 8321021c54)