jesseduffield/lazygit · error

Alias nodes are not supported

Error message

Alias nodes are not supported

What it means

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.

Source

Thrown at pkg/utils/yaml_utils/yaml_utils.go:261

				childPath = fmt.Sprintf("%s.%s", path, name)
			}
			err := walk(childNode, childPath, callback)
			if err != nil {
				return err
			}
		}
	case yaml.SequenceNode:
		for i := range len(node.Content) {
			childPath := fmt.Sprintf("%s[%d]", path, i)
			err := walk(node.Content[i], childPath, callback)
			if err != nil {
				return err
			}
		}
	case yaml.ScalarNode:
		// nothing to do
	case yaml.AliasNode:
		return errors.New("Alias nodes are not supported")
	}

	return nil
}

func YamlMarshal(node *yaml.Node) ([]byte, error) {
	var buffer bytes.Buffer
	encoder := yaml.NewEncoder(&buffer)
	encoder.SetIndent(2)

	err := encoder.Encode(node)
	return buffer.Bytes(), err
}

View on GitHub (pinned to c477a2959b)

Solutions

  1. Expand the anchors/aliases in the YAML file (inline the duplicated blocks) — easiest reliable fix.
  2. Alternatively re-marshal the file through a parser that resolves aliases (yaml.Unmarshal to map then re-marshal) to normalize it.
  3. If aliases are load-bearing for you, keep them out of the sections lazygit rewrites.

Example fix

# before
base: &base
  a: 1
child:
  <<: *base
  b: 2
# after
base:
  a: 1
child:
  a: 1
  b: 2
Defensive patterns

Strategy: validation

Validate before calling

// Reject files containing anchors/aliases before path-based operations:
func hasAliases(node *yaml.Node) bool {
    var found bool
    var check func(*yaml.Node)
    check = func(n *yaml.Node) {
        if n == nil || found {
            return
        }
        if n.Kind == yaml.AliasNode {
            found = true
            return
        }
        for _, c := range n.Content {
            check(c)
        }
    }
    check(node)
    return found
}

Type guard

func isAliasNode(n *yaml.Node) bool {
    return n != nil && n.Kind == yaml.AliasNode
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15). Data as JSON: /api/errors/5484611f517a92c1. Report an issue: GitHub.