{"record":{"id":"b1ccd7e89215d7df","repo":"farion1231/cc-switch","slug":"toml","errorCode":null,"errorMessage":"TOML 内容不能为空","messagePattern":"TOML 内容不能为空","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/utils/tomlUtils.ts","lineNumber":55,"sourceCode":"  }\n\n  // stringify 默认会带换行，做一次 trim 以适配文本框展示\n  return stringifyToml(obj).trim();\n};\n\n/**\n * 将 TOML 文本转换为 McpServerSpec 对象（单个服务器配置）\n * 支持两种格式：\n * 1. 直接的服务器配置（type, command, args 等）\n * 2. [mcp_servers.<id>] 格式（推荐，取第一个服务器）\n * 3. [mcp.servers.<id>] 错误格式（容错解析，同样取第一个服务器）\n * @param tomlText TOML 文本\n * @returns McpServer 对象\n * @throws 解析或转换失败时抛出错误\n */\nexport const tomlToMcpServer = (tomlText: string): McpServerSpec => {\n  if (!tomlText.trim()) {\n    throw new Error(\"TOML 内容不能为空\");\n  }\n\n  const parsed = parseToml(normalizeTomlText(tomlText));\n\n  // 情况 1: 直接是服务器配置（包含 type/command/url 等字段）\n  if (\n    parsed.type ||\n    parsed.command ||\n    parsed.url ||\n    parsed.args ||\n    parsed.env\n  ) {\n    return normalizeServerConfig(parsed);\n  }\n\n  // 情况 2: [mcp_servers.<id>] 格式（推荐）\n  if (parsed.mcp_servers && typeof parsed.mcp_servers === \"object\") {\n    const serverIds = Object.keys(parsed.mcp_servers);","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/farion1231/cc-switch/blob/a2e22f330273a5b6ffa87cb8b82b624601bac562/src/utils/tomlUtils.ts#L37-L73","documentation":"tomlToMcpServer rejects empty or whitespace-only input before any parsing ('TOML content cannot be empty'). It is the first guard on the MCP server import path that converts pasted TOML text into an McpServerSpec.","triggerScenarios":"tomlToMcpServer('') or tomlToMcpServer('\\n\\t') - importing from an empty textarea, or a clipboard/file read that returned nothing.","commonSituations":"User clicks import before pasting; the selected file is empty; an upstream copy step failed silently and produced an empty string.","solutions":["Guard with trim() and show a 'paste a config first' hint instead of calling","Disable the import button while the input is blank","Skip the conversion entirely for empty strings"],"exampleFix":"// before\nconst server = tomlToMcpServer(text); // throws on empty input\n\n// after\nif (!text.trim()) {\n  setImportError(\"Paste an MCP server TOML config first\");\n  return;\n}\nconst server = tomlToMcpServer(text);","handlingStrategy":"validation","validationCode":"if (!tomlText.trim()) {\n  setImportError(\"Paste an MCP server TOML config first\");\n  return;\n}\nconst server = tomlToMcpServer(tomlText);","typeGuard":null,"tryCatchPattern":"try {\n  const server = tomlToMcpServer(tomlText);\n} catch (e) {\n  if (e instanceof Error && e.message === \"TOML 内容不能为空\") {\n    setImportError(\"Paste a config first\");\n  } else {\n    throw e;\n  }\n}","preventionTips":["Disable the import button while the input is blank","Trim editor text before invoking the converter","Treat an empty file/clipboard result as a skip, not a parse call"],"tags":["toml","mcp","validation","import"],"backgroundTag":null,"analyzedSha":"a2e22f330273a5b6ffa87cb8b82b624601bac562","analyzedAt":"2026-08-16T03:46:07.889Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}