{"record":{"id":"28439b145c7d7f15","repo":"Hmbown/CodeWhale","slug":"invalid-json-payload-at-key-mcp-server-definition","errorCode":null,"errorMessage":"invalid JSON payload at key {MCP_SERVER_DEFINITIONS_KEY}; contents were omitted","messagePattern":"invalid JSON payload at key (.+?); contents were omitted","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/cli/src/lib.rs","lineNumber":4364,"sourceCode":"\n    match parse_mcp_server_definitions(&raw) {\n        Ok(definitions) => definitions,\n        Err(err) => {\n            eprintln!(\n                \"warning: failed to parse persisted MCP server definitions ({MCP_SERVER_DEFINITIONS_KEY}): {err}\"\n            );\n            Vec::new()\n        }\n    }\n}\n\nfn parse_mcp_server_definitions(raw: &str) -> Result<Vec<McpServerDefinition>> {\n    if let Ok(parsed) = serde_json::from_str::<Vec<McpServerDefinition>>(raw) {\n        return Ok(parsed);\n    }\n\n    let unwrapped: String = serde_json::from_str(raw).map_err(|_| {\n        anyhow!(\"invalid JSON payload at key {MCP_SERVER_DEFINITIONS_KEY}; contents were omitted\")\n    })?;\n    serde_json::from_str::<Vec<McpServerDefinition>>(&unwrapped).map_err(|_| {\n        anyhow!(\n            \"invalid MCP server definition list in key {MCP_SERVER_DEFINITIONS_KEY}; contents were omitted\"\n        )\n    })\n}\n\nfn persist_mcp_server_definitions(\n    store: &mut ConfigStore,\n    definitions: &[McpServerDefinition],\n) -> Result<()> {\n    let encoded =\n        serde_json::to_string(definitions).context(\"failed to encode MCP server definitions\")?;\n    store\n        .config\n        .set_value(MCP_SERVER_DEFINITIONS_KEY, &encoded)?;\n    store.save()","sourceCodeStart":4346,"sourceCodeEnd":4382,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/cli/src/lib.rs#L4346-L4382","documentation":"The config key mcp.server_definitions must hold a JSON array of MCP server definitions (or a JSON string wrapping such an array for legacy double-encoded values). When the raw value is not parseable as JSON at all, parse_mcp_server_definitions raises this error with contents deliberately omitted. The interactive load path downgrades it to a warning and starts the stdio MCP server with an empty list.","triggerScenarios":"Hand-editing the config and writing a TOML-style value at mcp.server_definitions (e.g. server_definitions = [{ command = \"npx\" }]) instead of JSON; a truncated config; an external tool rewriting the extras table into a non-JSON form.","commonSituations":"Migrating configs between CLI versions; editing with the wrong syntax assumption; tooling that re-renders extras entries (the class of bug fixed for #4727 where TOML re-quoting broke JSON payloads).","solutions":["Replace the value with a valid JSON array of definitions, matching the current McpServerDefinition schema","Or delete the key and re-register servers via the mcp commands so the CLI re-persists canonical JSON","If servers vanished after the warning, check stderr for the accompanying \"failed to parse persisted MCP server definitions\" line"],"exampleFix":"# before (config, invalid — TOML not JSON)\n [mcp] \n server_definitions = [{ command = \"npx\", args = [\"-y\", \"fs\"] }] \n\n# after\n [mcp] \n server_definitions = '[{\"command\":\"npx\",\"args\":[\"-y\",\"fs\"]}]'","handlingStrategy":"validation","validationCode":"function assert_mcp_definitions_json(config_path) {\n  const raw = readTomlKey(config_path, \"mcp.server_definitions\");\n  if (raw != null) JSON.parse(raw); // throws before launch if not JSON\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Manage mcp.server_definitions only through the CLI's mcp commands — never hand-edit it as TOML","After any external config rewrite, check stderr for the persisted-definitions warning before relying on servers","Keep a backup of a known-good JSON payload for the key"],"tags":["cli","mcp","config","json","parsing","rust"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}