paperclipai/paperclip · error · Error

--payload must be a JSON object

Error message

--payload must be a JSON object

What it means

Thrown by parseJsonObject() used by `paperclipai agent wake` when --payload parses as valid JSON but is not a plain object (it is a number, string, array, or boolean). JSON.parse itself succeeded; the runtime type check rejected the result. A malformed JSON string would instead surface as a JSON.parse SyntaxError (not this message).

Source

Thrown at cli/src/commands/client/agent.ts:866

              }
            }
          }
          console.log("");
          console.log("# Run this in your shell before launching codex/claude:");
          console.log(exportsText);
        } catch (err) {
          handleCommandError(err);
        }
      }),
    { includeCompany: false },
  );
}

function parseJsonObject(value: string | undefined): Record<string, unknown> | undefined {
  if (value === undefined) return undefined;
  const parsed = JSON.parse(value) as unknown;
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
    throw new Error("--payload must be a JSON object");
  }
  return parsed as Record<string, unknown>;
}

function parseJson(value: string): unknown {
  return JSON.parse(value) as unknown;
}

function parseCsv(value: string | undefined): string[] {
  if (!value) return [];
  return value.split(",").map((part) => part.trim()).filter(Boolean);
}

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Wrap the value as an object: --payload '{"key":"value"}'.
  2. If you have no payload, omit --payload entirely (parseJsonObject returns undefined for no value).
  3. Validate locally first: `echo '{}' | jq empty` then pass it.

Example fix

// before
paperclipai agent wake agt_1 --payload '["a","b"]'
// after
paperclipai agent wake agt_1 --payload '{"items":["a","b"]}'
Defensive patterns

Strategy: validation

Validate before calling

function asJsonObject(value: string | undefined): Record<string, unknown> | undefined {
  if (value === undefined) return undefined;
  const parsed = JSON.parse(value) as unknown;
  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
    throw new Error(`--payload must be a JSON object (got ${Array.isArray(parsed) ? 'array' : typeof parsed})`);
  }
  return parsed as Record<string, unknown>;
}

Type guard

function isPlainObject(v: unknown): v is Record<string, unknown> {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}

Try / catch

try { parseJsonObject(opts.payload); }
catch (err) {
  const msg = err instanceof Error ? err.message : String(err);
  if (msg === '--payload must be a JSON object') {
    console.error('Pass --payload as a JSON object, e.g. --payload \'{}\'');
    process.exit(2);
  }
  throw err; // JSON.parse syntax error
}

Prevention

When it happens

Trigger: Passing --payload '[1,2,3]' (array), --payload '"x"' (string), --payload '42' (number), or --payload 'true' to `agent wake`. The wakeup contract requires an object payload.

Common situations: User wrapped a single value in quotes thinking it becomes an object. User passed a JSON array of items. User forgot the surrounding braces for key/value pairs.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/b7e2774de317291b. Report an issue: GitHub.