{"record":{"id":"71605730c3694c43","repo":"googleapis/mcp-toolbox","slug":"unable-to-convert-entrybody-to-mapslice","errorCode":null,"errorMessage":"unable to convert entryBody to MapSlice","messagePattern":"unable to convert entryBody to MapSlice","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/internal/config.go","lineNumber":372,"sourceCode":"func transformDocs(kind string, input yaml.MapSlice) ([]yaml.MapSlice, error) {\n\tvar transformed []yaml.MapSlice\n\tfor _, entry := range input {\n\t\tentryName, ok := entry.Key.(string)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected non-string key for entry in '%s': %v\", kind, entry.Key)\n\t\t}\n\t\tentryBody := processValue(entry.Value, kind == \"toolset\")\n\n\t\tcurrentTransformed := yaml.MapSlice{\n\t\t\t{Key: \"kind\", Value: kind},\n\t\t\t{Key: \"name\", Value: entryName},\n\t\t}\n\n\t\t// Merge the transformed body into our result\n\t\tif bodySlice, ok := entryBody.(yaml.MapSlice); ok {\n\t\t\tcurrentTransformed = append(currentTransformed, bodySlice...)\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"unable to convert entryBody to MapSlice\")\n\t\t}\n\t\ttransformed = append(transformed, currentTransformed)\n\t}\n\treturn transformed, nil\n}\n\n// processValue recursively looks for MapSlices to rename 'kind' -> 'type'\nfunc processValue(v any, isToolset bool) any {\n\tswitch val := v.(type) {\n\tcase yaml.MapSlice:\n\t\t// creating a new MapSlice is safer for recursive transformation\n\t\tnewVal := make(yaml.MapSlice, len(val))\n\t\tfor i, item := range val {\n\t\t\t// Perform renaming\n\t\t\tif item.Key == \"kind\" {\n\t\t\t\titem.Key = \"type\"\n\t\t\t}\n\t\t\t// Recursive call for nested values (e.g., nested objects or lists)","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/cmd/internal/config.go#L354-L390","documentation":"After processing an entry's value with processValue, transformDocs expects the result to be a yaml.MapSlice so it can merge it into the transformed document. This error is thrown when processValue returns something else (e.g. a different map type or scalar) for an entry body.","triggerScenarios":"The value of an entry under a kind section is not a mapping that processValue converts to yaml.MapSlice — e.g. a source defined as a scalar (`sources:\n  mypg: postgres`) or a list instead of a map of fields.","commonSituations":"Malformed config where a source/tool definition body was accidentally replaced with a plain string or list, often from YAML indentation mistakes that flatten the structure.","solutions":["Ensure each entry body is a YAML mapping with fields like kind/description/parameters","Check indentation so the entry's fields nest under the entry name","Unmarshal with yaml.MapSlice (v2) semantics; avoid mixing yaml.v3 types"],"exampleFix":"// before\nsources:\n  mypg: postgres\n// after\nsources:\n  mypg:\n    kind: postgres\n    uri: ...","handlingStrategy":"validation","validationCode":"for name, val := range section {\n  if _, ok := val.(map[interface{}]interface{}); !ok {\n    return fmt.Errorf(\"entry %v must be a mapping, got %T\", name, val)\n  }\n}","typeGuard":"func isMapSlice(v interface{}) bool { _, ok := v.(yaml.MapSlice); return ok }","tryCatchPattern":"cfg, err := parser.ConvertConfig(ctx, data)\nif err != nil {\n  if strings.Contains(err.Error(), \"entryBody to MapSlice\") {\n    // entry body is not a mapping; inspect YAML structure\n  }\n  return err\n}","preventionTips":["Ensure every source/tool entry body is an indented YAML mapping","Check indentation with a YAML linter","Never define a resource as a bare scalar or list"],"tags":["yaml","config-parsing","type-mismatch"],"backgroundTag":"config-structure-invalid","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"}