coleam00/Archon · error
MCP config ${serverName}.env must be a JSON object of string
Error message
MCP config ${serverName}.env must be a JSON object of string values (got ${describeJsonType(server.env)}) What it means
If a server entry defines env, it must be a JSON object whose values are strings (each value is env-var interpolated). A non-object env, or an array/null, cannot hold key/value environment variables, so expandEnvVars throws naming the server and the offending type.
Source
Thrown at packages/providers/src/mcp/config.ts:68
function expandEnvVars(
config: Record<string, unknown>,
envSource: EnvSource
): {
expanded: Record<string, unknown>;
missingVars: string[];
} {
const result: Record<string, unknown> = {};
const missingVars: string[] = [];
for (const [serverName, serverConfig] of Object.entries(config)) {
if (typeof serverConfig !== 'object' || serverConfig === null || Array.isArray(serverConfig)) {
throw new Error(
`MCP server "${serverName}" must be a JSON object (got ${describeJsonType(serverConfig)})`
);
}
const server = { ...(serverConfig as Record<string, unknown>) };
if (server.env !== undefined) {
if (typeof server.env !== 'object' || server.env === null || Array.isArray(server.env)) {
throw new Error(
`MCP config ${serverName}.env must be a JSON object of string values (got ${describeJsonType(server.env)})`
);
}
server.env = expandEnvVarsInRecord(
server.env as Record<string, unknown>,
missingVars,
envSource,
`${serverName}.env`
);
}
if (server.headers !== undefined) {
if (
typeof server.headers !== 'object' ||
server.headers === null ||
Array.isArray(server.headers)
) {
throw new Error(
`MCP config ${serverName}.headers must be a JSON object of string values (got ${describeJsonType(server.headers)})`View on GitHub (pinned to 0773b97458)
Solutions
- Convert env to an object of strings: {"env": {"DEBUG": "1"}}.
- Delete the env key entirely if there are no variables (undefined is allowed).
- Split comma or newline separated env strings into individual object entries.
Example fix
// before
{"server": {"command": "node", "env": "DEBUG=1\nLOG=info"}}
// after
{"server": {"command": "node", "env": {"DEBUG": "1", "LOG": "info"}}} Defensive patterns
Strategy: validation
Validate before calling
const s = cfg[serverName];
if ('env' in s && (typeof s.env !== 'object' || s.env === null || Array.isArray(s.env))) {
throw new Error(`${serverName}.env must be an object of strings`);
} Type guard
const isEnvObject = (v: unknown): v is Record<string, string> => typeof v === 'object' && v !== null && !Array.isArray(v) && Object.values(v).every((x) => typeof x === 'string');
Prevention
- Never paste dotenv 'KEY=VALUE' lines into the env field; convert them to key/value pairs.
- Omit env entirely instead of writing null when there are no variables.
- Lint the config with a schema requiring env?: {[k: string]: string}.
When it happens
Trigger: loadMcpConfig where a server has "env": "DEBUG=1" (string), "env": ["A=1"] (array), or "env": null instead of an object of strings.
Common situations: Migrating from dotenv-style lines pasted into JSON; YAML-to-JSON conversion producing lists; a script setting env to null when no vars exist; shell export syntax copied verbatim.
Related errors
- MCP config ${fieldPath}.${key} must be a string (got ${descr
- MCP server "${serverName}" must be a JSON object (got ${desc
- MCP config ${serverName}.headers must be a JSON object of st
- MCP config cannot mix top-level "mcpServers" with other keys
- MCP config field "mcpServers" must be a JSON object: ${mcpPa
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/acc5153ed44d4e27.
Report an issue: GitHub.