{"record":{"id":"559543d91d353d3e","repo":"affaan-m/ECC","slug":"mcp-config-must-be-a-json-object","errorCode":null,"errorMessage":"MCP config must be a JSON object","messagePattern":"MCP config must be a JSON object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/mcp-config.js","lineNumber":14,"sourceCode":"'use strict';\n\nfunction parseDisabledMcpServers(value) {\n  return [...new Set(\n    String(value || '')\n      .split(',')\n      .map((entry) => entry.trim())\n      .filter(Boolean)\n  )];\n}\n\nfunction filterMcpConfig(config, disabledServerNames = []) {\n  if (!config || typeof config !== 'object' || Array.isArray(config)) {\n    throw new Error('MCP config must be a JSON object');\n  }\n\n  const servers = config.mcpServers;\n  if (!servers || typeof servers !== 'object' || Array.isArray(servers)) {\n    throw new Error('MCP config must include an mcpServers object');\n  }\n\n  const disabled = new Set(parseDisabledMcpServers(disabledServerNames));\n  if (disabled.size === 0) {\n    return {\n      config: {\n        ...config,\n        mcpServers: { ...servers },\n      },\n      removed: [],\n    };\n  }\n","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/mcp-config.js#L1-L32","documentation":"filterMcpConfig filters disabled MCP servers out of a parsed mcp config. It requires the config to be a plain JSON object; null, arrays, and primitives cannot carry an mcpServers mapping and are rejected before any filtering occurs.","triggerScenarios":"Calling filterMcpConfig(null), filterMcpConfig([]), filterMcpConfig('...'), or passing a parsed JSON file whose top level is an array instead of an object.","commonSituations":"An mcp-configs file saved as a JSON array of configs; a failed read yielding null passed straight through; passing the raw file text string instead of JSON.parse output.","solutions":["Pass the parsed JSON object, e.g. JSON.parse(fs.readFileSync(path,'utf8')).","Fix the config file so its top level is an object, not an array.","Check for a null/undefined return from an earlier load step before filtering."],"exampleFix":"// before\nfilterMcpConfig(rawConfigText, ['legacy'])\n// after\nconst parsed = JSON.parse(rawConfigText)\nfilterMcpConfig(parsed, ['legacy'])","handlingStrategy":"type-guard","validationCode":"let parsed\ntry { parsed = typeof cfg === 'string' ? JSON.parse(cfg) : cfg } catch { throw new Error('Config is not valid JSON') }\nif (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('MCP config must be a JSON object')","typeGuard":"function isJsonObject(x) {\n  return x !== null && typeof x === 'object' && !Array.isArray(x)\n}\nif (!isJsonObject(config)) throw new TypeError('Expected a JSON object for MCP config')","tryCatchPattern":"try {\n  const filtered = filterMcpConfig(config, disabled)\n} catch (err) {\n  if (err.message === 'MCP config must be a JSON object') {\n    console.error('Config must be a parsed JSON object with an mcpServers key')\n  } else throw err\n}","preventionTips":["Always JSON.parse config file contents before filtering.","Validate config file top-level shape after editing mcp-configs files.","Never pass null from a failed loader straight into downstream calls.","Keep mcp config files as a single top-level object, not arrays."],"tags":["mcp","validation","json","type-check"],"backgroundTag":"invalid-config-value","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}