{"record":{"id":"5113dcfd0b4e5e32","repo":"googleapis/mcp-toolbox","slug":"s-missing-kind-field-or-it-is-not-a-string","errorCode":null,"errorMessage":"%s missing 'kind' field or it is not a string","messagePattern":"(.+?) missing 'kind' field or it is not a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/server/config.go","lineNumber":205,"sourceCode":"\n\tdecoder := yaml.NewDecoder(bytes.NewReader(raw))\n\tfor index, doc := range file.Docs {\n\t\tif doc == nil || doc.Body == nil {\n\t\t\tcontinue\n\t\t}\n\t\tdocIndex := index + 1\n\t\tvar resource map[string]any\n\t\tif err := decoder.DecodeFromNodeContext(ctx, doc.Body, &resource); err != nil {\n\t\t\tif len(file.Docs) > 1 {\n\t\t\t\treturn nil, nil, nil, nil, nil, nil, fmt.Errorf(\"document %d: %s\", docIndex, yaml.FormatError(err, false, false))\n\t\t\t}\n\t\t\treturn nil, nil, nil, nil, nil, nil, fmt.Errorf(\"unable to decode YAML document: %s\", yaml.FormatError(err, false, false))\n\t\t}\n\t\tvar kind, name string\n\t\tvar ok bool\n\t\tif kind, ok = resource[\"kind\"].(string); !ok {\n\t\t\tif len(file.Docs) > 1 {\n\t\t\t\treturn 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))\n\t\t\t}\n\t\t\treturn nil, nil, nil, nil, nil, nil, fmt.Errorf(\"missing 'kind' field or it is not a string: %v\", resource)\n\t\t}\n\t\tif name, ok = resource[\"name\"].(string); !ok {\n\t\t\t// A `kind: group` may omit `name` to target the default nameless group;\n\t\t\t// every other resource requires a name.\n\t\t\tif kind == \"group\" {\n\t\t\t\tif rawName, present := resource[\"name\"]; !present || rawName == nil {\n\t\t\t\t\tname, ok = \"\", true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif !ok {\n\t\t\tif len(file.Docs) > 1 {\n\t\t\t\tfallbackToken := keyToken(doc.Body, \"name\")\n\t\t\t\tif fallbackToken == nil {\n\t\t\t\t\tfallbackToken = keyToken(doc.Body, \"kind\")\n\t\t\t\t}","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/server/config.go#L187-L223","documentation":"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.","triggerScenarios":"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]).","commonSituations":"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.","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."],"exampleFix":"// before\nsources:\n  my-pg:\n    kind: postgres\n    host: localhost\n// after\ntoolbox:\n  kind: tool\n  name: my-tool\nsources:\n  my-pg:\n    kind: postgres\n    host: localhost","handlingStrategy":"validation","validationCode":"func validateTopLevelKind(doc map[string]any) error {\n    v, ok := doc[\"kind\"]\n    if !ok {\n        return fmt.Errorf(\"document missing required top-level 'kind' field\")\n    }\n    if _, isStr := v.(string); !isStr {\n        return fmt.Errorf(\"'kind' must be a string, got %T\", v)\n    }\n    return nil\n}","typeGuard":"kindVal, ok := doc[\"kind\"]\nisStringKind := ok && func(v any) bool { _, isStr := v.(string); return isStr }(kindVal)","tryCatchPattern":null,"preventionTips":["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."],"tags":["yaml","config","validation"],"backgroundTag":"missing-yaml-kind-field","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}