farion1231/cc-switch · error · Error

服务器配置必须是对象

Error message

服务器配置必须是对象

What it means

normalizeServerConfig receives the extracted candidate server object and rejects anything that is not an object ('服务器配置必须是对象' — 'server config must be an object'). This is a defensive gate inside the converter: extraction steps usually yield TOML tables, but a scalar or array can slip through when a section like mcp_servers is mapped to a plain value instead of tables.

Source

Thrown at src/utils/tomlUtils.ts:103

      if (serverIds.length > 0) {
        const firstServer = mcpObj.servers[serverIds[0]];
        return normalizeServerConfig(firstServer);
      }
    }
  }

  throw new Error(
    "无法识别的 TOML 格式。请提供单个 MCP 服务器配置,或使用 [mcp_servers.<id>] 格式",
  );
};

/**
 * 规范化服务器配置对象为 McpServer 格式
 * 保留所有字段(包括扩展字段如 timeout_ms)
 */
function normalizeServerConfig(config: any): McpServerSpec {
  if (!config || typeof config !== "object") {
    throw new Error("服务器配置必须是对象");
  }

  const type = (config.type as string) || "stdio";

  // 已知字段列表(用于后续排除)
  const knownFields = new Set<string>();

  if (type === "stdio") {
    if (!config.command || typeof config.command !== "string") {
      throw new Error("stdio 类型的 MCP 服务器必须包含 command 字段");
    }

    const server: McpServerSpec = {
      type: "stdio",
      command: config.command,
    };
    knownFields.add("type");
    knownFields.add("command");

View on GitHub (pinned to 0b5da51016)

Solutions

  1. Make the server entry a TOML table: put it under [mcp_servers.<id>] or as top-level keys
  2. Pre-parse with the same parseToml call and verify the extracted value is an object before importing
  3. Show the extracted shape (table vs string vs array) in the import preview

Example fix

# before
mcp_servers = "fetch"

# after
[mcp_servers.fetch]
type = "stdio"
command = "uvx"
Defensive patterns

Strategy: type-guard

Validate before calling

const candidate = extractFirstServer(parseToml(normalizeTomlText(tomlText)));
if (!isRecord(candidate)) {
  // tell the user the server entry must be a table
}

Type guard

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

Try / catch

try {
  const server = tomlToMcpServer(tomlText);
} catch (error) {
  if (error instanceof Error && error.message === '服务器配置必须是对象') {
    // hint: wrap keys under a [mcp_servers.<id>] table header
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: TOML where the value flowing into normalizeServerConfig is a scalar or array — e.g. 'mcp_servers = "fetch"' or a mixed paste whose first extracted entry is a list.

Common situations: A table header [mcp_servers.name] was omitted so the value became a plain key/value; converting JSON fixtures to TOML incorrectly.

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


AI-assisted analysis of farion1231/cc-switch@0b5da51016 (2026-08-20). Data as JSON: /api/errors/aa0464cc1b0c2839. Report an issue: GitHub.