googleapis/mcp-toolbox · error
toolset %q declared more than once
Error message
toolset %q declared more than once
What it means
UnmarshalPrimitiveConfig rejects duplicate toolset names: after unmarshaling a "toolset" document, it checks `toolsetGroups[name]` and errors if a toolset with that name was already declared. Duplicate names would silently replace an existing toolset group, so the parser fails fast.
Source
Thrown at internal/server/config.go:292
toolConfigs = make(ToolConfigs)
}
if _, exists := toolConfigs[name]; exists {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("tool %q declared more than once", name)
}
toolConfigs[name] = c
case "toolset":
c, err := UnmarshalYAMLToolsetConfig(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 toolsetGroups == nil {
toolsetGroups = make(map[string]group.GroupConfig)
}
if _, exists := toolsetGroups[name]; exists {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("toolset %q declared more than once", name)
}
toolsetGroups[name] = group.GroupConfig{Name: name, ToolNames: c.ToolNames}
case "embeddingModel":
c, err := UnmarshalYAMLEmbeddingModelConfig(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 embeddingModelConfigs == nil {
embeddingModelConfigs = make(EmbeddingModelConfigs)
}
if _, exists := embeddingModelConfigs[name]; exists {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("embeddingModel %q declared more than once", name)
}
embeddingModelConfigs[name] = c
case "prompt":View on GitHub (pinned to 8cc6e09de2)
Solutions
- Rename one of the two toolsets named in the error to a unique name.
- Delete the redundant duplicate toolset if unnecessary.
- Grep the config for the duplicated name across all `---` documents.
- If both toolsets share a purpose, merge their `toolNames` lists into one.
Example fix
// before
toolsets:
default:
toolNames: [a, b]
default:
toolNames: [c]
// after
toolsets:
default:
toolNames: [a, b]
admin-tools:
toolNames: [c] Defensive patterns
Strategy: validation
Validate before calling
func rawDuplicateToolsetNames(data string) []string {
var seen, dups []string
inSection := false
for _, line := range strings.Split(data, "\n") {
trimmed := strings.TrimSpace(line)
if strings.HasPrefix(line, "toolsets:") { inSection = true; continue }
if strings.HasPrefix(line, "tools:") || strings.HasPrefix(line, "prompts:") { inSection = false }
if inSection && strings.HasSuffix(trimmed, ":") && !strings.HasPrefix(trimmed, "-") {
name := strings.TrimSuffix(trimmed, ":")
if slices.Contains(seen, name) { dups = append(dups, name) }
seen = append(seen, name)
}
}
return dups
} Type guard
func isDuplicateToolsetErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "toolset") && strings.Contains(err.Error(), "declared more than once")
} Try / catch
cfg, err := server.ParseConfig(ctx, yamlBytes)
if err != nil {
if strings.Contains(err.Error(), "declared more than once") {
return fmt.Errorf("dedupe toolset names in toolbox.yaml: %w", err)
}
return err
} Prevention
- Name toolsets after their audience/purpose (e.g., read-only-tools) to avoid collisions when merging.
- Search all documents of a multi-doc file for a name before reusing it.
- Enable a duplicate-key lint rule in yamllint configuration.
When it happens
Trigger: Calling ParseConfig with a YAML file (including multi-document files) that declares two `toolset` resources with the same name, triggering the `exists` check on `toolsetGroups`.
Common situations: Appending a second toolset block with a copy-pasted name; merging configs from teammates where both defined a toolset called `default` or `all-tools`.
Related errors
- source %q declared more than once
- authService %q declared more than once
- tool %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/a8262714475fb1d9.
Report an issue: GitHub.