googleapis/mcp-toolbox · error

more than one default (nameless) group declared; only one is

Error message

more than one default (nameless) group declared; only one is allowed

What it means

A config may contain at most one nameless (default) group; the default group applies to tools without an explicit group. If two group entries with an empty name decode successfully, UnmarshalPrimitiveConfig fails at internal/server/config.go:338 with this explicit message.

Source

Thrown at internal/server/config.go:338

			}
			if _, exists := promptConfigs[name]; exists {
				return nil, nil, nil, nil, nil, nil, fmt.Errorf("prompt %q declared more than once", name)
			}
			promptConfigs[name] = c
		case "group":
			c, err := UnmarshalYAMLGroupConfig(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 groupConfigs == nil {
				groupConfigs = make(GroupConfigs)
			}
			if _, exists := groupConfigs[name]; exists {
				if name == "" {
					return nil, nil, nil, nil, nil, nil, fmt.Errorf("more than one default (nameless) group declared; only one is allowed")
				}
				return nil, nil, nil, nil, nil, nil, fmt.Errorf("group %q declared more than once", name)
			}
			groupConfigs[name] = c
		default:
			if len(file.Docs) > 1 {
				return nil, nil, nil, nil, nil, nil, fmt.Errorf("%s invalid kind %q", formatDocLocation(docIndex, keyToken(doc.Body, "kind"), doc.Body), kind)
			}
			return nil, nil, nil, nil, nil, nil, fmt.Errorf("invalid kind %s", kind)
		}
	}
	// Fold legacy toolsets into groups. An explicit `kind: group` of the same name
	// takes precedence over a toolset (matching the prior server-side behavior); warn
	// when a toolset is shadowed this way.
	if len(toolsetGroups) > 0 {
		if groupConfigs == nil {
			groupConfigs = make(GroupConfigs)
		}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Remove one of the nameless group blocks so only a single default group remains
  2. Give the other group an explicit unique name if both sets of tools must be grouped
  3. After merging configs, deduplicate group definitions before deploying

Example fix

# before
kind: group
:
  toolIds: [tool-a]
---
kind: group
:
  toolIds: [tool-b]
# after
kind: group
:
  toolIds: [tool-a, tool-b]
Defensive patterns

Strategy: validation

Validate before calling

// Count nameless groups in a config before parsing
text, _ := os.ReadFile(path)
docs := strings.Split(string(text), "\n---")
defaults := 0
for _, d := range docs {
	var doc struct {
		Kind string `yaml:"kind"`
		Name string `yaml:"serverRef"`
	}
	if yaml.Unmarshal([]byte(d), &doc) == nil && doc.Kind == "group" && strings.TrimSpace(d) != "" {
		// a group doc with no name key is a default group; count via key scan
		if !regexp.MustCompile(`(?m)^\s+[\w-]+:`).MatchString(strings.TrimPrefix(d, "kind: group")) == false && !strings.Contains(d, "my-group") {
			defaults++
		}
	}
}
if defaults > 1 {
	return fmt.Errorf("%d default groups found; keep at most one", defaults)
}

Try / catch

if _, _, _, _, _, _, err := server.ParseConfig(ctx, cfg); err != nil {
	if strings.Contains(err.Error(), "default (nameless) group") {
		log.Fatalf("config has multiple default groups: %v", err)
	}
	return err
}

Prevention

When it happens

Trigger: Two 'group' resources in the YAML both have an empty name (two anonymous/default group blocks), so the second insertion into the groupConfigs map hits the exists check and the name=='' branch.

Common situations: Repeating a default group block when merging configs; YAML anchors accidentally producing two nameless groups; copy-pasting a group template and deleting its name in more than one place.

Related errors


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