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

  1. Rename one of the duplicate sources so each name is unique.
  2. If both documents are identical, delete one.
  3. If you intended one source reused by many tools, declare it once and reference it by name from tools.
  4. 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

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


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