{"record":{"id":"b1ccd7e89215d7df","repo":"farion1231/cc-switch","slug":"toml","errorCode":null,"errorMessage":"TOML 内容不能为空","messagePattern":"TOML 内容不能为空","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","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/0b5da510168914b251481654a568c3ffacd62cf4/src/utils/tomlUtils.ts#L37-L73","documentation":"tomlToMcpServer converts pasted TOML into a single McpServerSpec and rejects blank input up front: if tomlText.trim() is empty it throws 'TOML 内容不能为空' ('TOML content cannot be empty') before any parsing. Every later step — parseToml, direct-config detection, [mcp_servers.<id>] and [mcp.servers.<id>] extraction — assumes at least one non-whitespace character.","triggerScenarios":"The MCP import/paste dialog calls tomlToMcpServer('') or with whitespace-only text — e.g. submit fired before the paste happened, or the textarea was cleared.","commonSituations":"Import button enabled on an empty dialog; clipboard paste failed silently; user presses submit to 'see what happens'.","solutions":["Disable the import action while the TOML textarea is blank","Trim and early-return with an inline message instead of relying on the throw","Pre-check with the same trim() condition the function uses"],"exampleFix":"// before\nconst server = tomlToMcpServer(tomlText); // throws on ''\n\n// after\nif (!tomlText.trim()) {\n  showImportError('Paste a TOML server config first');\n  return;\n}\nconst server = tomlToMcpServer(tomlText);","handlingStrategy":"validation","validationCode":"if (!tomlText.trim()) {\n  showImportError('Paste a TOML server config first');\n  return;\n}\nconst server = tomlToMcpServer(tomlText);","typeGuard":null,"tryCatchPattern":"try {\n  const server = tomlToMcpServer(tomlText);\n} catch (error) {\n  if (error instanceof Error && error.message === 'TOML 内容不能为空') {\n    // keep the import dialog open with an inline hint\n  } else {\n    throw error;\n  }\n}","preventionTips":["Disable the import action on an empty textarea","Trim editor content before deciding to parse","Confirm the paste actually landed before enabling submit"],"tags":["toml","mcp","validation","import"],"backgroundTag":"empty-required-input","analyzedSha":"0b5da510168914b251481654a568c3ffacd62cf4","analyzedAt":"2026-08-20T14:29:00.113Z","contentChangedAt":"2026-08-20T14:29:00.113Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}