{"record":{"id":"f5dee88478658c17","repo":"abiosoft/colima","slug":"uneven-children-of-d-found-for-mapping-node","errorCode":null,"errorMessage":"uneven children of %d found for mapping node","messagePattern":"uneven children of (.+?) found for mapping node","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/yamlutil/yaml.go","lineNumber":144,"sourceCode":"\t\tif key == \"\" || key == \"-\" { // no yaml tag is present\n\t\t\tcontinue\n\t\t}\n\n\t\tif parentKey != \"\" {\n\t\t\tkey = parentKey + \".\" + key\n\t\t}\n\t\tval := val.Field(i)\n\n\t\ttraverseConfig(key, val.Interface(), vals)\n\t}\n\n}\n\nfunc traverseNode(parentKey string, node *yaml.Node, vals map[string]*yaml.Node) error {\n\tswitch node.Kind {\n\tcase yaml.MappingNode:\n\t\tif l := len(node.Content); l%2 != 0 {\n\t\t\treturn fmt.Errorf(\"uneven children of %d found for mapping node\", l)\n\t\t}\n\t\tfor i := 0; i < len(node.Content); i += 2 {\n\t\t\tif i > 1 {\n\t\t\t\t// fix jumbled comments\n\t\t\t\tif cn := node.Content[i]; cn.HeadComment != \"\" {\n\t\t\t\t\tif strings.Index(cn.HeadComment, \"#\") == 0 {\n\t\t\t\t\t\tcn.HeadComment = \"\\n\" + cn.HeadComment\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tkey := node.Content[i].Value\n\t\t\tval := node.Content[i+1]\n\t\t\tif parentKey != \"\" {\n\t\t\t\tkey = parentKey + \".\" + key\n\t\t\t}\n\t\t\tvals[key] = val\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/abiosoft/colima/blob/c3a5f9184d83a197184f897a9f07eb3c01b3bc88/util/yamlutil/yaml.go#L126-L162","documentation":"traverseNode (util/yamlutil/yaml.go:144) enforces YAML's structural rule while walking the embedded default: a mapping node's Content list alternates key, value, key, value, so its length must be even. An odd length means a key with no value — malformed mapping content that strict unmarshal would normally have rejected earlier, so this is defense-in-depth over the embedded asset. It propagates up to callers as 'error traversing yaml node' (error 293).","triggerScenarios":"An embedded/defaults/colima.yaml whose mapping content is unbalanced after hand edits (a value deleted but its key left, or vice versa), only reachable when the earlier unmarshal leniently accepted the document as a raw Node.","commonSituations":"Fork edits and scripted rewrites of the defaults file; merge conflicts resolved by deleting lines; YAML reformatters with bugs producing dangling keys.","solutions":["Run the defaults file through a strict YAML linter and fix the reported unbalanced mapping","Restore embedded/defaults/colima.yaml from upstream git and reapply edits","Change defaults via colima's config layer instead of the embedded template","Add CI that round-trips Save() over defaults to catch structural breakage"],"exampleFix":"# before\nmounts:\n  - location\n\n# after\nmounts:\n  - location: /mnt/data","handlingStrategy":"validation","validationCode":"// structural check for mapping nodes before traversal\nfunc mappingBalanced(n *yaml.Node) bool {\n    return n.Kind != yaml.MappingNode || len(n.Content)%2 == 0\n}","typeGuard":null,"tryCatchPattern":"if err := util.Save(cfg, file); err != nil {\n    if strings.Contains(err.Error(), \"uneven children\") {\n        // embedded default has a dangling key — restore the asset / reinstall\n        return fmt.Errorf(\"colima defaults structurally broken — reinstall: %w\", err)\n    }\n    return err\n}","preventionTips":["Lint embedded YAML for dangling keys in CI","Never script-edit the defaults with sed/regex — edit by hand and test","Restore defaults from git when in doubt","Prefer colima's config layer for default changes"],"tags":["yaml","mapping","validation","embedded"],"backgroundTag":null,"analyzedSha":"c3a5f9184d83a197184f897a9f07eb3c01b3bc88","analyzedAt":"2026-08-15T18:58:08.334Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}