siyuan-note/siyuan · warning
duplicate variable %q
Error message
duplicate variable %q
What it means
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.
Source
Thrown at kernel/mcp/client/mcp.go:566
return err
}
key := environmentKey(name, goos)
if inherited[key] {
return fmt.Errorf("duplicate inherited variable %q", name)
}
inherited[key] = true
}
explicit := map[string]bool{}
for name, value := range server.Env {
if err := validateEnvironmentName(name); err != nil {
return err
}
if strings.ContainsRune(value, '\x00') {
return fmt.Errorf("variable %q contains NUL", name)
}
key := environmentKey(name, goos)
if explicit[key] {
return fmt.Errorf("duplicate variable %q", name)
}
explicit[key] = true
}
return nil
}
// ValidateMCPServerEnvironment 校验当前平台上的 stdio 环境变量配置。
func ValidateMCPServerEnvironment(server conf.MCPServer) error {
return validateMCPServerEnvironment(server, runtime.GOOS)
}
func defaultMCPEnvironmentNames(goos string) []string {
if goos == "windows" {
return []string{"APPDATA", "HOMEDRIVE", "HOMEPATH", "LOCALAPPDATA", "PATH", "PATHEXT",
"PROCESSOR_ARCHITECTURE", "PROGRAMFILES", "SYSTEMDRIVE", "SYSTEMROOT", "TEMP", "USERNAME", "USERPROFILE"}
}
return []string{"HOME", "LOGNAME", "PATH", "SHELL", "TERM"}
}View on GitHub (pinned to 251596fc0d)
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.
Example fix
// before (windows)
"env": {"PATH": "a", "Path": "b"}
// after
"env": {"PATH": "b"} Defensive patterns
Strategy: validation
Validate before calling
import (
"runtime"
"strings"
)
func dedupeExplicit(env map[string]string) map[string]string {
out := map[string]string{}
for k, v := range env {
key := k
if runtime.GOOS == "windows" { key = strings.ToUpper(k) }
out[key] = v
}
return out
} Prevention
- On Windows, normalize Env keys to upper case at config-load time.
- Validate with ValidateMCPServerEnvironment before save.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/2c73085ae2fa5eda.
Report an issue: GitHub.