googleapis/mcp-toolbox · error
source %q declared more than once
Error message
source %q declared more than once
What it means
Thrown by UnmarshalPrimitiveConfig when two documents in the parsed YAML declare a source with the same 'name'. SourceConfigs is a map keyed by name, so duplicate declarations would silently overwrite each other; the parser rejects them instead.
Source
Thrown at internal/server/config.go:244
return nil, nil, nil, nil, nil, nil, fmt.Errorf("missing 'name' field or it is not a string")
}
// remove 'kind' from map for strict unmarshaling
delete(resource, "kind")
switch kind {
case "source":
c, err := UnmarshalYAMLSourceConfig(ctx, name, resource)
if err != nil {
if len(file.Docs) > 1 {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("document %d: error unmarshaling %s %q: %w", docIndex, kind, name, err)
}
return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %w", kind, err)
}
if sourceConfigs == nil {
sourceConfigs = make(SourceConfigs)
}
if _, exists := sourceConfigs[name]; exists {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("source %q declared more than once", name)
}
sourceConfigs[name] = c
case "authService":
c, err := UnmarshalYAMLAuthServiceConfig(ctx, name, resource)
if err != nil {
if len(file.Docs) > 1 {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("document %d: error unmarshaling %s %q: %w", docIndex, kind, name, err)
}
return nil, nil, nil, nil, nil, nil, fmt.Errorf("error unmarshaling %s: %w", kind, err)
}
if authServiceConfigs == nil {
authServiceConfigs = make(AuthServiceConfigs)
}
if _, exists := authServiceConfigs[name]; exists {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("authService %q declared more than once", name)
}
authServiceConfigs[name] = c
case "tool":View on GitHub (pinned to 8cc6e09de2)
Solutions
- Rename one of the duplicate sources so each name is unique.
- If both documents are identical, delete one.
- If you intended one source reused by many tools, declare it once and reference it by name from tools.
- Search the file (or concatenated files passed to --tools-file/--sources-file) for duplicated source names.
Example fix
// before kind: source name: my-pg ... --- kind: source name: my-pg // after kind: source name: my-pg ... --- kind: source name: my-pg-replica
Defensive patterns
Strategy: validation
Validate before calling
func checkUniqueSourceNames(docs []map[string]any) error {
seen := map[string]int{}
for i, doc := range docs {
if k, _ := doc["kind"].(string); k == "source" {
n, _ := doc["name"].(string)
if prev, dup := seen[n]; dup {
return fmt.Errorf("source %q declared in documents %d and %d", n, prev+1, i+1)
}
seen[n] = i
}
}
return nil
} Prevention
- Keep a naming convention prefix per environment (e.g. prod-, dev-).
- Grep for 'name:' under kind: source blocks before merging config changes.
- Declare a shared source once and reference it from tools.
- Add a uniqueness check script to CI for multi-document YAML files.
When it happens
Trigger: ParseConfig on a multi-document YAML file where two 'kind: source' documents share the identical name string.
Common situations: Copy-pasting a source document and forgetting to rename it; merging config files that both define 'my-pg'; templating loops emitting duplicate names.
Related errors
- authService %q declared more than once
- tool %q declared more than once
- toolset %q declared more than once
- embeddingModel %q declared more than once
- prompt %q declared more than once
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/d3699252064ef655.
Report an issue: GitHub.