{"record":{"id":"c6220a998722ae1a","repo":"JuliusBrussee/caveman","slug":"path-is-not-a-json-object","errorCode":null,"errorMessage":"${path} is not a JSON object","messagePattern":"(.+?) is not a JSON object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":6980,"sourceCode":"    if (fd !== undefined) try { closeSync(fd); } catch { /* original error wins */ }\n    try { unlinkSync(temp); } catch { /* no partial */ }\n    throw error;\n  }\n}\n\nfunction durableUnlink(path: string): void {\n  try {\n    unlinkSync(path);\n    fsyncParentDirectory(path);\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n  }\n}\n\nfunction parseJsonFileObject(path: string, bytes: Buffer | null): Record<string, unknown> {\n  if (!bytes || bytes.length === 0) return {};\n  const parsed = JSON.parse(bytes.toString(\"utf8\"));\n  if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) throw new Error(`${path} is not a JSON object`);\n  return parsed as Record<string, unknown>;\n}\n\nfunction nativeMcpBinaryRequired(): string {\n  const compatible = probeMcpBinary();\n  if (!compatible) throw new Error(\"caveman-mcp not found; run `caveman setup --install`\");\n  if (!compatible.probe.current) throw new Error(`caveman-mcp ${compatible.probe.version} lacks current mcp_recovery capability; run \\`caveman setup --install\\``);\n  return compatible.binary;\n}\n\nfunction nativeProxyBinaryRequired(gw: string): void {\n  if (wrapMode(gw) !== \"local\") return;\n  const binary = resolveGoBin(\"caveman-proxy\", \"CAVEMAN_PROXY_BIN\");\n  if (!binary) throw new Error(\"caveman-proxy not found; run `caveman setup --install`\");\n  const probe = probeVersionedBinary(binary, \"native_runtime_v1\");\n  if (!probe.current) throw new Error(`caveman-proxy ${probe.version} lacks current native_runtime_v1 capability; run \\`caveman setup --install\\``);\n}\n","sourceCodeStart":6962,"sourceCodeEnd":6998,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L6962-L6998","documentation":"Thrown by parseJsonFileObject when a config file has content but its parsed JSON is not a plain object — e.g. a top-level array, string, number, or a scalar like `true`. MCP config management requires JSON object documents and refuses to operate on (and overwrite) files with an unexpected top-level shape.","triggerScenarios":"parseJsonFileObject reads non-empty bytes whose JSON.parse result is null, a non-object, or an Array; e.g. a config file containing `[]` or `\"text\"`.","commonSituations":"A config file overwritten by another tool with an array or scalar, an empty placeholder replaced with quoted text, or a truncated/invalid write that still parses as non-object JSON.","solutions":["Inspect the file: `cat <path>` and check its top-level JSON type","Convert the content to a JSON object (e.g. `{}`) or restore it from a backup","If the file is disposable, delete it and let the CLI regenerate it","Re-run the MCP setup command after fixing the file"],"exampleFix":"// before (config.json)\n[]\n// after\n{}","handlingStrategy":"validation","validationCode":"const bytes = fs.readFileSync(configPath);\nconst parsed = JSON.parse(bytes.toString(\"utf8\"));\nif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n  console.error(`${configPath} must contain a JSON object at the top level`);\n}","typeGuard":"function isJsonObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  runMcpCommand();\n} catch (e) {\n  if (String(e.message).includes(\"is not a JSON object\")) {\n    console.error(`Reset the named file to a JSON object (e.g. {}) or restore a backup.`);\n  }\n}","preventionTips":["Keep config files as top-level JSON objects; never replace them with arrays or scalars","Validate JSON files after any external tool writes them","Keep backups of config files before migrating between tools"],"tags":["json","config","validation","mcp"],"backgroundTag":"json-parse-error","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}