{"record":{"id":"2c73085ae2fa5eda","repo":"siyuan-note/siyuan","slug":"duplicate-variable-q","errorCode":null,"errorMessage":"duplicate variable %q","messagePattern":"duplicate variable %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/mcp/client/mcp.go","lineNumber":566,"sourceCode":"\t\t\treturn err\n\t\t}\n\t\tkey := environmentKey(name, goos)\n\t\tif inherited[key] {\n\t\t\treturn fmt.Errorf(\"duplicate inherited variable %q\", name)\n\t\t}\n\t\tinherited[key] = true\n\t}\n\texplicit := map[string]bool{}\n\tfor name, value := range server.Env {\n\t\tif err := validateEnvironmentName(name); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif strings.ContainsRune(value, '\\x00') {\n\t\t\treturn fmt.Errorf(\"variable %q contains NUL\", name)\n\t\t}\n\t\tkey := environmentKey(name, goos)\n\t\tif explicit[key] {\n\t\t\treturn fmt.Errorf(\"duplicate variable %q\", name)\n\t\t}\n\t\texplicit[key] = true\n\t}\n\treturn nil\n}\n\n// ValidateMCPServerEnvironment 校验当前平台上的 stdio 环境变量配置。\nfunc ValidateMCPServerEnvironment(server conf.MCPServer) error {\n\treturn validateMCPServerEnvironment(server, runtime.GOOS)\n}\n\nfunc defaultMCPEnvironmentNames(goos string) []string {\n\tif goos == \"windows\" {\n\t\treturn []string{\"APPDATA\", \"HOMEDRIVE\", \"HOMEPATH\", \"LOCALAPPDATA\", \"PATH\", \"PATHEXT\",\n\t\t\t\"PROCESSOR_ARCHITECTURE\", \"PROGRAMFILES\", \"SYSTEMDRIVE\", \"SYSTEMROOT\", \"TEMP\", \"USERNAME\", \"USERPROFILE\"}\n\t}\n\treturn []string{\"HOME\", \"LOGNAME\", \"PATH\", \"SHELL\", \"TERM\"}\n}","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/mcp/client/mcp.go#L548-L584","documentation":"Validation error from validateMCPServerEnvironment: two keys in server.Env normalize to the same environmentKey. A Go map cannot hold two byte-identical keys, so on Unix this is effectively unreachable; on Windows, where environmentKey upper-cases the name, case-variant keys like 'Path' and 'PATH' collide. The second occurrence is reported via %q.","triggerScenarios":"On Windows (runtime.GOOS == \"windows\"), server.Env contains two keys differing only in case, e.g. {\"PATH\": \"a\", \"Path\": \"b\"}. Both reduce to environmentKey \"PATH\"; the second triggers the error.","commonSituations":"Cross-platform config that tried to set the same variable under two casings; merging configs from different authors; a JSON merger that did not normalize case on Windows.","solutions":["On Windows, keep only one casing of each variable name in Env and remove the case-variant duplicate.","Normalize Env keys to a canonical case at config-load time on Windows.","Run ValidateMCPServerEnvironment to confirm the duplicate is gone."],"exampleFix":"// before (windows)\n\"env\": {\"PATH\": \"a\", \"Path\": \"b\"}\n// after\n\"env\": {\"PATH\": \"b\"}","handlingStrategy":"validation","validationCode":"import (\n    \"runtime\"\n    \"strings\"\n)\nfunc dedupeExplicit(env map[string]string) map[string]string {\n    out := map[string]string{}\n    for k, v := range env {\n        key := k\n        if runtime.GOOS == \"windows\" { key = strings.ToUpper(k) }\n        out[key] = v\n    }\n    return out\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["On Windows, normalize Env keys to upper case at config-load time.","Validate with ValidateMCPServerEnvironment before save."],"tags":["mcp","environment","config-validation","windows"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}