{"record":{"id":"5484611f517a92c1","repo":"jesseduffield/lazygit","slug":"alias-nodes-are-not-supported","errorCode":null,"errorMessage":"Alias nodes are not supported","messagePattern":"Alias nodes are not supported","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/utils/yaml_utils/yaml_utils.go","lineNumber":261,"sourceCode":"\t\t\t\tchildPath = fmt.Sprintf(\"%s.%s\", path, name)\n\t\t\t}\n\t\t\terr := walk(childNode, childPath, callback)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase yaml.SequenceNode:\n\t\tfor i := range len(node.Content) {\n\t\t\tchildPath := fmt.Sprintf(\"%s[%d]\", path, i)\n\t\t\terr := walk(node.Content[i], childPath, callback)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase yaml.ScalarNode:\n\t\t// nothing to do\n\tcase yaml.AliasNode:\n\t\treturn errors.New(\"Alias nodes are not supported\")\n\t}\n\n\treturn nil\n}\n\nfunc YamlMarshal(node *yaml.Node) ([]byte, error) {\n\tvar buffer bytes.Buffer\n\tencoder := yaml.NewEncoder(&buffer)\n\tencoder.SetIndent(2)\n\n\terr := encoder.Encode(node)\n\treturn buffer.Bytes(), err\n}\n","sourceCodeStart":243,"sourceCodeEnd":275,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/utils/yaml_utils/yaml_utils.go#L243-L275","documentation":"The YAML walker only handles mapping, sequence, and scalar nodes. A node of Kind AliasNode (a YAML alias '*name' referencing an anchor '&name') makes the walk bail out, because resolving aliases is ambiguous for path-based operations like renaming or deleting keys. Note: gopkg.in/yaml.v3 does not resolve anchors/aliases into a node tree automatically when node-parsing.","triggerScenarios":"Walking a config file that uses YAML anchors and aliases (e.g. reused blocks via '&defaults' / '*defaults'); any key path enumeration over such a file hits the alias node and stops.","commonSituations":"Users DRY-ing up their config.yml with anchors; sharing config snippets via aliases; then a lazygit version migration or key rename walks the file and fails.","solutions":["Expand the anchors/aliases in the YAML file (inline the duplicated blocks) — easiest reliable fix.","Alternatively re-marshal the file through a parser that resolves aliases (yaml.Unmarshal to map then re-marshal) to normalize it.","If aliases are load-bearing for you, keep them out of the sections lazygit rewrites."],"exampleFix":"# before\nbase: &base\n  a: 1\nchild:\n  <<: *base\n  b: 2\n# after\nbase:\n  a: 1\nchild:\n  a: 1\n  b: 2","handlingStrategy":"validation","validationCode":"// Reject files containing anchors/aliases before path-based operations:\nfunc hasAliases(node *yaml.Node) bool {\n    var found bool\n    var check func(*yaml.Node)\n    check = func(n *yaml.Node) {\n        if n == nil || found {\n            return\n        }\n        if n.Kind == yaml.AliasNode {\n            found = true\n            return\n        }\n        for _, c := range n.Content {\n            check(c)\n        }\n    }\n    check(node)\n    return found\n}","typeGuard":"func isAliasNode(n *yaml.Node) bool {\n    return n != nil && n.Kind == yaml.AliasNode\n}","tryCatchPattern":null,"preventionTips":["Avoid anchors/aliases in YAML files that tools rewrite in place (config.yml, state files).","Normalize shared YAML through marshal/unmarshal to expand aliases before processing.","If you maintain a YAML utility, decide alias policy up front and validate at parse time."],"tags":["yaml","anchors","aliases","config"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}