googleapis/mcp-toolbox · error
%s missing 'kind' field or it is not a string
Error message
%s missing 'kind' field or it is not a string
What it means
This error is thrown by UnmarshalPrimitiveConfig while parsing a toolbox YAML file when a YAML document's top-level resource map does not contain a 'kind' key, or its value cannot be asserted as a string. 'kind' is required to route the document to the correct config type (source, tool, authService, etc.). When the file contains multiple YAML documents (len(file.Docs) > 1), this location-annotated variant is returned so the developer can find the offending document.
Source
Thrown at internal/server/config.go:205
decoder := yaml.NewDecoder(bytes.NewReader(raw))
for index, doc := range file.Docs {
if doc == nil || doc.Body == nil {
continue
}
docIndex := index + 1
var resource map[string]any
if err := decoder.DecodeFromNodeContext(ctx, doc.Body, &resource); err != nil {
if len(file.Docs) > 1 {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("document %d: %s", docIndex, yaml.FormatError(err, false, false))
}
return nil, nil, nil, nil, nil, nil, fmt.Errorf("unable to decode YAML document: %s", yaml.FormatError(err, false, false))
}
var kind, name string
var ok bool
if kind, ok = resource["kind"].(string); !ok {
if len(file.Docs) > 1 {
return nil, nil, nil, nil, nil, nil, fmt.Errorf("%s missing 'kind' field or it is not a string", formatDocLocation(docIndex, keyToken(doc.Body, "kind"), doc.Body))
}
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")
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Add a top-level 'kind' field with a string value (e.g. kind: tool) to the offending YAML document.
- If the file has multiple '---'-separated documents, check each document has its own kind at the document root, not nested.
- Verify kind is not quoted inconsistently or typed as a number/boolean; force a string (kind: "123").
- Run go run . --prebuilt my.yaml or a YAML linter to confirm the root structure parses to a map with kind.
Example fix
// before
sources:
my-pg:
kind: postgres
host: localhost
// after
toolbox:
kind: tool
name: my-tool
sources:
my-pg:
kind: postgres
host: localhost Defensive patterns
Strategy: validation
Validate before calling
func validateTopLevelKind(doc map[string]any) error {
v, ok := doc["kind"]
if !ok {
return fmt.Errorf("document missing required top-level 'kind' field")
}
if _, isStr := v.(string); !isStr {
return fmt.Errorf("'kind' must be a string, got %T", v)
}
return nil
} Type guard
kindVal, ok := doc["kind"]
isStringKind := ok && func(v any) bool { _, isStr := v.(string); return isStr }(kindVal) Prevention
- Always start every YAML document with a top-level kind: line.
- Use multi-document files sparingly and keep each doc's structure identical (kind, name, then body).
- Validate config files in CI with a YAML schema linter before deploying.
- Never place 'kind' under an indented parent key.
When it happens
Trigger: Calling ParseConfig (via UnmarshalPrimitiveConfig) on YAML where a document's root is a map with no 'kind' key, or where kind's value is a non-string (e.g. kind: 123, kind: true, kind: [tool]).
Common situations: Hand-written YAML files omitting the kind field; copying a snippet without its kind line; accidental indentation causing kind to nest under another key; CI tooling generating YAML with numeric kinds.
Related errors
- doc %d: unexpected non-string key in input: %v
- doc %d: invalid config format at key %q: %w
- doc %d: invalid config format at key %q: expected nested for
- missing 'kind' field or it is not a string: %v
- %s missing 'name' field or it is not a string
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/5113dcfd0b4e5e32.
Report an issue: GitHub.