coleam00/Archon · error

MCP config must be a JSON object (Record<string, ServerConfi

Error message

MCP config must be a JSON object (Record<string, ServerConfig>): ${mcpPath}

What it means

The top-level JSON document must be an object whose keys are server names. JSON files whose root is an array, a string, a number, or null have no server map to iterate, so loadMcpConfig throws with the config path and the expected Record<string, ServerConfig> shape.

Source

Thrown at packages/providers/src/mcp/config.ts:154

    raw = await readFile(fullPath, 'utf-8');
  } catch (err) {
    const e = err as NodeJS.ErrnoException;
    if (e.code === 'ENOENT') {
      throw new Error(`MCP config file not found: ${mcpPath} (resolved to ${fullPath})`);
    }
    throw new Error(`Failed to read MCP config file: ${mcpPath} - ${e.message}`);
  }

  let parsed: Record<string, unknown>;
  try {
    parsed = JSON.parse(raw) as Record<string, unknown>;
  } catch (parseErr) {
    const detail = (parseErr as SyntaxError).message;
    throw new Error(`MCP config file is not valid JSON: ${mcpPath} - ${detail}`);
  }

  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
    throw new Error(`MCP config must be a JSON object (Record<string, ServerConfig>): ${mcpPath}`);
  }

  const normalized = normalizeMcpConfig(parsed, mcpPath);
  const { expanded, missingVars } = expandEnvVars(normalized, envSource);
  const serverNames = Object.keys(expanded);
  return { servers: expanded, serverNames, missingVars };
}

View on GitHub (pinned to 0773b97458)

Solutions

  1. Wrap the content in an object keyed by server name, or use {"mcpServers": {...}}.
  2. Convert an array of server descriptors into a map (key by the server's name field).
  3. For zero servers, write {} rather than null or [].

Example fix

// before
[{"name": "fs", "command": "npx"}]
// after
{"fs": {"command": "npx"}}
Defensive patterns

Strategy: type-guard

Validate before calling

const parsed: unknown = JSON.parse(readFileSync(mcpPath, 'utf-8'));
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
  throw new Error(`${mcpPath} must be a JSON object keyed by server name`);
}

Type guard

const isJsonObject = (v: unknown): v is Record<string, unknown> =>
  typeof v === 'object' && v !== null && !Array.isArray(v);

Prevention

When it happens

Trigger: loadMcpConfig on files like ["server1", "server2"], "npx ...", or null (JSON 'null' literal), all of which parse fine but are not objects.

Common situations: A list of server names exported by a script instead of a map; an empty file containing just 'null'; pasting a CLI command into the config; a generator serializing an array of server descriptors.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/10930edd64c2ec23. Report an issue: GitHub.