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

  1. Rename one of the two toolsets named in the error to a unique name.
  2. Delete the redundant duplicate toolset if unnecessary.
  3. Grep the config for the duplicated name across all `---` documents.
  4. 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

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


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/a8262714475fb1d9. Report an issue: GitHub.