googleapis/mcp-toolbox · error

%s missing 'name' field or it is not a string

Error message

%s missing 'name' field or it is not a string

What it means

Thrown by UnmarshalPrimitiveConfig after the kind is resolved: every resource (except a nameless 'kind: group') must have a top-level 'name' whose value is a string. When the file has multiple YAML documents, this error is prefixed with a document location (using a fallback token from the 'name' or 'kind' key) so the offending document can be identified.

Source

Thrown at internal/server/config.go:224

			}
			return nil, nil, nil, nil, nil, nil, fmt.Errorf("missing 'kind' field or it is not a string: %v", resource)
		}
		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)
			}

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Add a unique string 'name' field at the document root next to kind.
  2. Confirm name is a scalar string, not a number or nested map.
  3. For group documents that intentionally omit name, verify kind is exactly 'group' (the only kind allowed to omit name).
  4. Check indentation so name is at the document root level.
  5. Locate the document via the prefix/line info in the error message.

Example fix

// before
document 2:
kind: tool
# name missing
// after
kind: tool
name: query-users
Defensive patterns

Strategy: validation

Validate before calling

func validateDocsHaveNames(docs []map[string]any) error {
    for i, doc := range docs {
        kind, _ := doc["kind"].(string)
        if kind == "group" {
            continue // group may omit name
        }
        if _, ok := doc["name"].(string); !ok {
            return fmt.Errorf("document %d (kind=%s): 'name' must be present and a string", i+1, kind)
        }
    }
    return nil
}

Type guard

n, present := doc["name"]
hasStringName := present && func(v any) bool { _, isStr := v.(string); return isStr }(n)

Prevention

When it happens

Trigger: ParseConfig on a multi-document YAML file where a document has kind set but no string 'name' at the root (missing, null, numeric, or a non-scalar).

Common situations: Defining several tools/sources with --- separators and forgetting name on one; renaming a resource and deleting the name key; generating YAML where name resolves to null.

Related errors


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