googleapis/mcp-toolbox · error

missing 'name' field or it is not a string

Error message

missing 'name' field or it is not a string

What it means

Single-document variant of the missing-'name' error: when the YAML file has only one document, UnmarshalPrimitiveConfig returns a bare 'missing 'name' field or it is not a string' without document-index decoration. The document's root map lacks a string 'name' key after kind was successfully resolved.

Source

Thrown at internal/server/config.go:226

		}
		if name, ok = resource["name"].(string); !ok {
			// A `kind: group` may omit `name` to target the default nameless group;
			// every other resource requires a name.
			if kind == "group" {
				if rawName, present := resource["name"]; !present || rawName == nil {
					name, ok = "", true
				}
			}
		}
		if !ok {
			if len(file.Docs) > 1 {
				fallbackToken := keyToken(doc.Body, "name")
				if fallbackToken == nil {
					fallbackToken = keyToken(doc.Body, "kind")
				}
				return nil, nil, nil, nil, nil, nil, fmt.Errorf("%s missing 'name' field or it is not a string", formatDocLocation(docIndex, fallbackToken, doc.Body))
			}
			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)

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Add 'name: <unique-string>' at the document root.
  2. Quote the name if it could parse as a number or boolean (name: "123").
  3. Ensure name is not indented under another key.
  4. If the resource is a nameless default group, set kind: group explicitly.

Example fix

// before
kind: source
sources: {...}
// after
kind: source
name: my-source
sources: {...}
Defensive patterns

Strategy: validation

Validate before calling

var root map[string]any
if err := yaml.Unmarshal([]byte(cfgText), &root); err != nil { return err }
if k, ok := root["kind"].(string); ok && k != "group" {
    if _, ok := root["name"].(string); !ok {
        return fmt.Errorf("config with kind %q requires a top-level string 'name'", k)
    }
}

Type guard

nameVal, ok := root["name"]
hasStringName := ok && func(v any) bool { _, isStr := v.(string); return isStr }(nameVal)

Try / catch

if err := server.ParseConfig(ctx, ...); err != nil {
    if strings.Contains(err.Error(), "missing 'name'") {
        log.Fatalf("add a top-level string 'name' to the document: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: ParseConfig on a single-document YAML where kind is a valid string but name is absent, null, or a non-string type.

Common situations: First-time config authors omitting name; templating engines emitting empty names; YAML like name: 42 (integer) failing the string assertion.

Related errors


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