Yeachan-Heo/oh-my-codex · error · Error

input must be a JSON object

Error message

input must be a JSON object

What it means

Thrown when the JSON passed via `--input <next>` parses successfully but is not a plain object — it's null, an array, or a primitive. The team API operations require a JSON object as input. Note this message surfaces via the outer catch as 'Invalid --input JSON: input must be a JSON object' because it's thrown inside the try block.

Source

Thrown at src/cli/team.ts:542

  const operation = resolveTeamApiOperation(args[0] || '');
  if (!operation) {
    throw new Error(`Usage: omx team api <operation> [--input <json>] [--json]\nSupported operations: ${TEAM_API_OPERATIONS.join(', ')}`);
  }
  let input: Record<string, unknown> = {};
  let json = false;
  for (let i = 1; i < args.length; i += 1) {
    const token = args[i];
    if (token === '--json') {
      json = true;
      continue;
    }
    if (token === '--input') {
      const next = args[i + 1];
      if (!next) throw new Error('Missing value after --input');
      try {
        const parsed = JSON.parse(next) as unknown;
        if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
          throw new Error('input must be a JSON object');
        }
        input = parsed as Record<string, unknown>;
      } catch (error) {
        throw new Error(`Invalid --input JSON: ${error instanceof Error ? error.message : String(error)}`);
      }
      i += 1;
      continue;
    }
    if (token.startsWith('--input=')) {
      const raw = token.slice('--input='.length);
      try {
        const parsed = JSON.parse(raw) as unknown;
        if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
          throw new Error('input must be a JSON object');
        }
        input = parsed as Record<string, unknown>;
      } catch (error) {
        throw new Error(`Invalid --input JSON: ${error instanceof Error ? error.message : String(error)}`);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Wrap the payload in an object: pass `{...}` with string keys/values.
  2. Check the target operation's expected input shape and match it as a JSON object.
  3. For arrays, wrap in an object key if the operation supports it, e.g. `--input '{"items":[...]}'`.

Example fix

# before
omx team api update --input '[{"id":1}]'
# after
omx team api update --input '{"id":1}'
Defensive patterns

Strategy: type-guard

Validate before calling

const parsed = JSON.parse(raw);
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
  console.error('--input must be a JSON object'); process.exit(2);
}

Type guard

const isJsonObject = (v: unknown): v is Record<string, unknown> =>
  typeof v === 'object' && v !== null && !Array.isArray(v);

Try / catch

try { await teamApi(args); } catch (e) {
  if (e instanceof Error && e.message.includes('must be a JSON object')) { /* wrap payload: --input `{"data":<raw>}` */ }
  else throw e;
}

Prevention

When it happens

Trigger: `--input '[1,2]'` (array), `--input '"str"'` or `--input 42` (primitive), or `--input null`.

Common situations: Users pasting a JSON array from an API response, or a primitive where an object payload is expected; forgetting the surrounding braces.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/9fbe6b3d4df9564f. Report an issue: GitHub.