{"record":{"id":"492fbb452ba7e05d","repo":"paperclipai/paperclip","slug":"expected-a-json-object-path","errorCode":null,"errorMessage":"Expected a JSON object: ${path}","messagePattern":"Expected a JSON object: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs","lineNumber":60,"sourceCode":"const ACTIVE_HTML_PATTERNS = [\n  /<script\\b/iu,\n  /<iframe\\b/iu,\n  /<object\\b/iu,\n  /<embed\\b/iu,\n  /<form\\b/iu,\n  /\\son[a-z]+\\s*=/iu,\n  /javascript\\s*:/iu,\n  /(?:src|href)\\s*=\\s*[\"'](?:https?:)?\\/\\//iu,\n];\n\nfunction json(value) {\n  return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\nasync function loadObject(path) {\n  const value = JSON.parse(await readFile(path, \"utf8\"));\n  if (value === null || Array.isArray(value) || typeof value !== \"object\") {\n    throw new Error(`Expected a JSON object: ${path}`);\n  }\n  return value;\n}\n\nexport function validateProtocolEvalHistoryDestination({\n  bucket,\n  prefix,\n  publicBaseUrl,\n}) {\n  if (!/^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/.test(bucket)) {\n    throw new Error(\n      \"RUNNER_PROTOCOL_EVAL_HISTORY_S3_BUCKET is not a valid bucket name\",\n    );\n  }\n  const normalizedPrefix = String(prefix ?? \"\").replace(/^\\/+|\\/+$/g, \"\");\n  if (\n    !normalizedPrefix ||\n    normalizedPrefix","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs#L42-L78","documentation":"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.","triggerScenarios":"Calling loadObject on a file containing a JSON array, a scalar (string/number/boolean), null, or invalid JSON that JSON.parse throws on first.","commonSituations":"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.","solutions":["Check the file content and wrap the top-level value in an object (e.g. {\"history\": [...]}).","Verify you passed the correct file path to the script.","Fix JSON syntax errors; ensure the file is non-empty and object-shaped."],"exampleFix":"// before (history.json)\n[{\"run\": 1}]\n// after\n{\"runs\": [{\"run\": 1}]}","handlingStrategy":"try-catch","validationCode":"const raw = JSON.parse(fs.readFileSync(path, 'utf8'));\nif (raw === null || Array.isArray(raw) || typeof raw !== 'object') throw new Error(`not a JSON object: ${path}`);","typeGuard":"function isJsonObject(v) { return v !== null && !Array.isArray(v) && typeof v === 'object'; }","tryCatchPattern":"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); }","preventionTips":["Verify the input file shape before invoking the publish script.","Lint/parse JSON files in CI to catch syntax errors early.","Don't point the script at array-form exports."],"tags":["json","validation","cli"],"backgroundTag":"json-parse-error","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}