microsoft/aspire · error · InvalidOperationException
The configuration file
Error message
The configuration file '{0}' must contain a JSON object. What it means
After parsing successfully, ReadConfigAsync requires the configuration file's root to be a JSON object. This error is thrown when the file contains valid JSON whose root is an array, string, number, or null instead of an object. The MCP config schema requires an object at the top level (e.g. { "mcpServers": { ... } }).
Solutions
- Rewrite the file so its top level is a JSON object, e.g. { "mcpServers": { ... } }, moving any array content under an appropriate key.
- Compare against a known-good mcp.json schema/template and re-add your entries inside the object.
- Delete the malformed file and re-run the CLI command to regenerate a correct skeleton, then re-apply settings.
- Validate with `jq 'type' <file>` — it should print "object" before you retry.
Example fix
// before
[ { "name": "fs" } ]
// after
{ "mcpServers": { "fs": { "command": "npx" } } } Defensive patterns
Strategy: validation
Validate before calling
using var doc = System.Text.Json.JsonDocument.Parse(File.ReadAllText(mcpJsonPath));
if (doc.RootElement.ValueKind != System.Text.Json.JsonValueKind.Object)
{
// rewrite the file so the top level is an object
} Try / catch
try
{
await command.ExecuteAsync();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("must contain a JSON object"))
{
// back up the file, regenerate config, re-add entries
} Prevention
- Keep the top level of mcp.json as an object (e.g. { "mcpServers": {...} }).
- Check `jq 'type' file` equals "object" before running commands against the config.
- Avoid merge tools that convert object configs into arrays.
When it happens
Trigger: Thrown when `root as JsonObject` is null after JsonNode.Parse succeeds — i.e. the config file's top-level value is an array (e.g. [ ... ]), a bare string/number, or null rather than an object.
Common situations: A hand-edit or merge tool replaced the object with an array; a script wrote a bare JSON list of servers instead of an object; the file was truncated to a fragment that happens to parse (e.g. just "null").
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- The configuration file
- The configuration file
- The configuration file
- Expected start of chat message object.
- Failed to parse JSON output into type
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/16fd307420a0f79e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/Agents/McpConfigFileHelper.cs:95
if (preprocessContent is not null)
{
content = preprocessContent(content);
}
JsonNode? root;
try
{
root = JsonNode.Parse(content);
}
catch (JsonException ex)
{
throw new InvalidOperationException(
string.Format(CultureInfo.CurrentCulture, AgentCommandStrings.MalformedConfigFileError, configFilePath), ex);
}
return root as JsonObject
?? throw new InvalidOperationException(
string.Format(CultureInfo.CurrentCulture, ErrorStrings.ConfigurationFileMustBeJsonObject, configFilePath));
}
}
View on GitHub (pinned to 25830f84bd)