{"record":{"id":"137d598d5f5da653","repo":"jesseduffield/lazygit","slug":"yaml-node-in-path-is-not-a-dictionary","errorCode":null,"errorMessage":"yaml node in path is not a dictionary","messagePattern":"yaml node in path is not a dictionary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/utils/yaml_utils/yaml_utils.go","lineNumber":99,"sourceCode":"}\n\n// Takes the root node of a yaml document, a path to a key, and a new name for the key.\n// Will rename the key to the new name if it exists, and do nothing otherwise.\nfunc RenameYamlKey(rootNode *yaml.Node, path []string, newKey string) (error, bool) {\n\t// Empty document: nothing to do.\n\tif len(rootNode.Content) == 0 {\n\t\treturn nil, false\n\t}\n\n\tbody := rootNode.Content[0]\n\n\treturn renameYamlKey(body, path, newKey)\n}\n\n// Recursive function to rename the YAML key.\nfunc renameYamlKey(node *yaml.Node, path []string, newKey string) (error, bool) {\n\tif node.Kind != yaml.MappingNode {\n\t\treturn errors.New(\"yaml node in path is not a dictionary\"), false\n\t}\n\n\tkeyNode, valueNode := LookupKey(node, path[0])\n\tif keyNode == nil {\n\t\treturn nil, false\n\t}\n\n\t// end of path reached: rename key\n\tif len(path) == 1 {\n\t\t// Check that new key doesn't exist yet\n\t\tif newKeyNode, _ := LookupKey(node, newKey); newKeyNode != nil {\n\t\t\treturn fmt.Errorf(\"new key `%s' already exists\", newKey), false\n\t\t}\n\n\t\tkeyNode.Value = newKey\n\t\treturn nil, true\n\t}\n","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/utils/yaml_utils/yaml_utils.go#L81-L117","documentation":"renameYamlKey walks a dot-separated path in a YAML document to rename a key. If a node along the path is not a MappingNode (it is a scalar or sequence), descent cannot continue and this error is returned with 'false' meaning nothing was renamed. It means the path you asked for crosses a non-dictionary YAML value.","triggerScenarios":"Calling the rename helper (used e.g. by worktree/branch rename flows that rewrite config.yml or lazygit state YAML) with a path whose intermediate element resolves to a list or plain string — e.g. path 'a.b.c' where 'b:' holds '- 1' or 'b: foo'.","commonSituations":"A hand-edited config.yml where a mapping was accidentally replaced by a scalar or list (missing indentation, '-' bullet in the wrong place); YAML anchors collapsing structure unexpectedly.","solutions":["Inspect the YAML file at the failing path; ensure every intermediate key holds a mapping (nested key: value pairs), not a scalar or list.","Fix indentation — a nested block indented wrong often parses as a scalar or sequence.","After correcting, retry the operation that triggered the rename."],"exampleFix":"# before (b is a scalar; path a.b.c invalid)\na:\n  b: oops\n# after\na:\n  b:\n    c: value","handlingStrategy":"validation","validationCode":"// Walk the path, asserting every intermediate node is a mapping before renaming:\nfunc pathIsAllMappings(node *yaml.Node, path []string) bool {\n    cur := node\n    for _, key := range path[:len(path)-1] {\n        if cur.Kind != yaml.MappingNode {\n            return false\n        }\n        _, next := LookupKey(cur, key)\n        if next == nil || next.Kind != yaml.MappingNode {\n            return false\n        }\n        cur = next\n    }\n    return cur.Kind == yaml.MappingNode\n}","typeGuard":"func isMappingNode(n *yaml.Node) bool {\n    return n != nil && n.Kind == yaml.MappingNode\n}","tryCatchPattern":null,"preventionTips":["Validate node kinds along the path before mutating YAML trees.","Hand-edit config files with a YAML-aware editor (schema hints) to avoid flattening maps into scalars.","Keep backups/VC on config files lazygit rewrites so structural mistakes are reversible."],"tags":["yaml","config","path-traversal"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}