paperclipai/paperclip · error · Error

Expected a JSON object: ${path}

Error message

Expected a JSON object: ${path}

What it means

Thrown by loadObject in the publish-runner-protocol-eval-history script. The file at the given path must parse to a JSON object (not null, not an array, not a primitive); otherwise the script refuses to load it because subsequent publish steps expect a keyed object.

Source

Thrown at packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs:60

const ACTIVE_HTML_PATTERNS = [
  /<script\b/iu,
  /<iframe\b/iu,
  /<object\b/iu,
  /<embed\b/iu,
  /<form\b/iu,
  /\son[a-z]+\s*=/iu,
  /javascript\s*:/iu,
  /(?:src|href)\s*=\s*["'](?:https?:)?\/\//iu,
];

function json(value) {
  return `${JSON.stringify(value, null, 2)}\n`;
}

async function loadObject(path) {
  const value = JSON.parse(await readFile(path, "utf8"));
  if (value === null || Array.isArray(value) || typeof value !== "object") {
    throw new Error(`Expected a JSON object: ${path}`);
  }
  return value;
}

export function validateProtocolEvalHistoryDestination({
  bucket,
  prefix,
  publicBaseUrl,
}) {
  if (!/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(bucket)) {
    throw new Error(
      "RUNNER_PROTOCOL_EVAL_HISTORY_S3_BUCKET is not a valid bucket name",
    );
  }
  const normalizedPrefix = String(prefix ?? "").replace(/^\/+|\/+$/g, "");
  if (
    !normalizedPrefix ||
    normalizedPrefix

View on GitHub (pinned to 01ad858492)

Solutions

  1. Check the file content and wrap the top-level value in an object (e.g. {"history": [...]}).
  2. Verify you passed the correct file path to the script.
  3. Fix JSON syntax errors; ensure the file is non-empty and object-shaped.

Example fix

// before (history.json)
[{"run": 1}]
// after
{"runs": [{"run": 1}]}
Defensive patterns

Strategy: try-catch

Validate before calling

const raw = JSON.parse(fs.readFileSync(path, 'utf8'));
if (raw === null || Array.isArray(raw) || typeof raw !== 'object') throw new Error(`not a JSON object: ${path}`);

Type guard

function isJsonObject(v) { return v !== null && !Array.isArray(v) && typeof v === 'object'; }

Try / catch

try { await loadObject(path); } catch (e) { console.error(`Check ${path}: must contain a top-level JSON object (not array/scalar/null) and valid JSON.`); process.exit(1); }

Prevention

When it happens

Trigger: Calling loadObject on a file containing a JSON array, a scalar (string/number/boolean), null, or invalid JSON that JSON.parse throws on first.

Common situations: Pointing the script at the wrong file (e.g. an array-form history export); a hand-edited or truncated JSON file; an empty file producing a parse error.

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 paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/492fbb452ba7e05d. Report an issue: GitHub.