{"record":{"id":"b19cb379b99c1be4","repo":"affaan-m/ECC","slug":"invalid-label-at-filepath-expected-a-json-o-b19cb3","errorCode":null,"errorMessage":"Invalid ${label} at ${filePath}: expected a JSON object","messagePattern":"Invalid (.+?) at (.+?): expected a JSON object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install-targets/kimi-project.js","lineNumber":19,"sourceCode":"const fs = require('fs');\nconst path = require('path');\n\nconst {\n  createInstallTargetAdapter,\n  createManagedOperation,\n  isForeignPlatformPath,\n} = require('./helpers');\n\nfunction readJsonObject(filePath, label) {\n  let parsed;\n  try {\n    parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));\n  } catch (error) {\n    throw new Error(`Failed to parse ${label} at ${filePath}: ${error.message}`);\n  }\n\n  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n    throw new Error(`Invalid ${label} at ${filePath}: expected a JSON object`);\n  }\n\n  return parsed;\n}\n\nfunction createMcpMergeOperation(moduleId, repoRoot, targetRoot) {\n  if (!repoRoot) {\n    throw new Error('repoRoot is required to plan Kimi MCP configuration');\n  }\n\n  const sourceRelativePath = '.mcp.json';\n  const sourcePath = path.join(repoRoot, sourceRelativePath);\n  if (!fs.existsSync(sourcePath) || !fs.statSync(sourcePath).isFile()) {\n    return null;\n  }\n\n  return createManagedOperation({\n    kind: 'merge-json',","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install-targets/kimi-project.js#L1-L37","documentation":"Thrown by readJsonObject in scripts/lib/install-targets/kimi-project.js after JSON.parse succeeds but the value is not a plain object — i.e. it is null, an array, or a primitive. The Kimi MCP merge logic iterates object keys via deepMergeJson, so a non-object top level would crash later; this guard fails fast. Same file/label as error 201 (the .mcp.json being merged).","triggerScenarios":"<repoRoot>/.mcp.json contains a JSON array (e.g. [ { ... } ]), a bare string/number/boolean, or null at the top level, but is syntactically valid JSON.","commonSituations":"User wrapped server definitions in [ ] thinking the file is a list; an empty config was serialized as null instead of {}; a generator emitted a scalar value; merge with a wrong-shape template.","solutions":["Open the named file and ensure the top level is a JSON object literal { ... }.","Use the standard MCP shape { \"mcpServers\": { ... } }.","If the intent is an empty config, write {} rather than [] or null.","Re-run the Kimi install plan."],"exampleFix":"// before (<repoRoot>/.mcp.json)\n[\n  { \"name\": \"context7\", \"command\": \"npx\" }\n]\n\n// after\n{\n  \"mcpServers\": {\n    \"context7\": { \"command\": \"npx\" }\n  }\n}","handlingStrategy":"type-guard","validationCode":"const v = JSON.parse(fs.readFileSync('.mcp.json', 'utf8'));\nif (!(v !== null && typeof v === 'object' && !Array.isArray(v))) {\n  throw new Error('.mcp.json top level must be a JSON object');\n}","typeGuard":"function isJsonObject(value) {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}","tryCatchPattern":"try {\n  readJsonObject(file, label);\n} catch (err) {\n  if (/expected a JSON object/.test(err.message)) {\n    console.error('Top-level JSON must be an object, not an array or primitive:', file);\n  }\n  throw err;\n}","preventionTips":["Always wrap MCP config as { \"mcpServers\": { ... } }.","Use a JSON-schema validator in your editor for .mcp.json.","Treat an empty config as {} — never as [] or null."],"tags":["json-schema","kimi","mcp-config","install-target"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}