{"record":{"id":"ac51a88a7de54e0a","repo":"mem0ai/mem0","slug":"config-is-not-a-json-object","errorCode":null,"errorMessage":"Config is not a JSON object","messagePattern":"Config is not a JSON object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"integrations/openclaw/cli/config-file.ts","lineNumber":65,"sourceCode":" * Returns {} only when the file doesn't exist (first-time setup).\n * Throws on parse errors to prevent writes from destroying existing config.\n */\nfunction readFullConfig(): Record<string, unknown> {\n  if (!exists(OPENCLAW_CONFIG_FILE)) {\n    return {};\n  }\n\n  const text = readText(OPENCLAW_CONFIG_FILE);\n\n  // Handle empty or whitespace-only files as first-time setup\n  if (!text.trim()) {\n    return {};\n  }\n\n  try {\n    const parsed = JSON.parse(text);\n    if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n      throw new Error(\"Config is not a JSON object\");\n    }\n    return parsed;\n  } catch (err) {\n    // Fail closed: throw so writes don't proceed with empty config\n    const msg = err instanceof Error ? err.message : String(err);\n    throw new Error(\n      `[openclaw-mem0] Failed to parse ${OPENCLAW_CONFIG_FILE}: ${msg}\\n` +\n        `Fix the JSON syntax error manually before running config commands.`,\n    );\n  }\n}\n\n/**\n * Write the full ~/.openclaw/openclaw.json.\n *\n * Re-reads the file immediately before writing and deep-merges the\n * `plugins` section so that fields written by other processes (e.g.\n * OpenClaw gateway adding `installs`, `slots`) are not clobbered.","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/integrations/openclaw/cli/config-file.ts#L47-L83","documentation":"Internal sentinel thrown while parsing ~/.openclaw/openclaw.json when the file parses as valid JSON but is not a plain object (null, array, number, string, boolean). It never surfaces raw: the surrounding catch rewraps it into the '[openclaw-mem0] Failed to parse ...' error, so users only see error 24. It exists to distinguish 'wrong shape' from 'syntax error' in the message.","triggerScenarios":"The config file containing a JSON array at top level (e.g. []), a bare string, a number, or literal null. The empty-file case is handled earlier (returns {} for first-time setup), so this only fires on non-empty, syntactically valid, non-object JSON.","commonSituations":"User edited openclaw.json and replaced the object with an array of settings; another tool wrote a JSON scalar to the file; hand-crafting config from a snippet that was itself a list.","solutions":["Open ~/.openclaw/openclaw.json and make the top-level value a JSON object: { ... }.","If the file is unrecoverable, back it up and delete it — readText treats a missing/empty file as first-time setup and recreates {}.","Validate with `jq type ~/.openclaw/openclaw.json` — it must print 'object'."],"exampleFix":"// before ~/.openclaw/openclaw.json\n[\n  { \"mode\": \"platform\" }\n]\n\n// after\n{\n  \"plugins\": {\n    \"openclaw-mem0\": { \"mode\": \"platform\" }\n  }\n}","handlingStrategy":"validation","validationCode":"const parsed = JSON.parse(text);\nif (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n  // reject before use\n}","typeGuard":"function isJsonObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","tryCatchPattern":null,"preventionTips":["Validate openclaw.json with `jq type` (must output 'object') after manual edits.","Never store a JSON array at the top level of the config file."],"tags":["config","json","filesystem","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}