nektos/act · error

failed to insert node %v into mapping %v unexpected type %v

Error message

failed to insert node %v into mapping %v unexpected type %v expected MappingNode

What it means

While recursively evaluating YAML nodes for ${{ }} interpolation (evaluateYamlNodeInternal), when a mapping key matches the insert directive (the 'x: ...' insert-on-key syntax used for matrix includes, i.e. the key matching insertDirective regexp), the corresponding value must itself be a yaml.MappingNode so its content can be merged into the parent mapping. This error fires when the insert directive's value is a scalar or sequence instead of a map.

Source

Thrown at pkg/runner/expression.go:298

		}
		k := node.Content[i*2]
		v := node.Content[i*2+1]
		ev, err := ee.evaluateYamlNodeInternal(ctx, v)
		if err != nil {
			return nil, err
		}
		if ev != nil {
			if err := changed(); err != nil {
				return nil, err
			}
		} else {
			ev = v
		}
		var sk string
		// Merge the nested map of the insert directive
		if k.Decode(&sk) == nil && insertDirective.MatchString(sk) {
			if ev.Kind != yaml.MappingNode {
				return nil, fmt.Errorf("failed to insert node %v into mapping %v unexpected type %v expected MappingNode", ev, node, ev.Kind)
			}
			if err := changed(); err != nil {
				return nil, err
			}
			ret.Content = append(ret.Content, ev.Content...)
		} else {
			ek, err := ee.evaluateYamlNodeInternal(ctx, k)
			if err != nil {
				return nil, err
			}
			if ek != nil {
				if err := changed(); err != nil {
					return nil, err
				}
			} else {
				ek = k
			}
			if ret != nil {

View on GitHub (pinned to 4f41128141)

Solutions

  1. Find the insert-directive key in your workflow YAML (run act with verbose logging to locate the node) and make its value a mapping (block of key: value pairs), or remove the key entirely.
  2. Use the standard matrix include syntax (strategy.matrix.include as a list) instead of the insert directive if you do not need it.
  3. Re-indent YAML so the value under the directive key parses as a map, not a scalar.

Example fix

# before (workflow yaml)
matrix:
  insert: [1, 2]

# after
matrix:
  os: [ubuntu-latest]
  insert:
    os: macos-latest
Defensive patterns

Strategy: type-guard

Validate before calling

python3 - <<'EOF'
import yaml
for f in ['.github/workflows/'+x for x in __import__('os').listdir('.github/workflows')]:
    y=yaml.safe_load(open(f))
    def walk(n):
        if isinstance(n,dict):
            for k,v in n.items():
                if k=='insert' and not isinstance(v,dict):
                    raise SystemExit(f'{f}: insert value must be a mapping, got {type(v).__name__}')
                walk(v)
        elif isinstance(n,list):
            for i in n: walk(i)
    walk(y)
print('insert directive ok')
EOF

Type guard

# YAML-level guard: value under an insert key must be a mapping node
func isMappingInsert(v any) bool {
    m, ok := v.(map[string]any)
    return ok && len(m) >= 0
}
// reject: insert: "scalar"  /  insert: [seq]

Prevention

When it happens

Trigger: In a workflow YAML where act evaluates expressions inside mappings (matrix generation with insert keys), writing something like 'insert: value-string' or 'insert: [a, b]' — the key matching the insert directive with a non-mapping value node.

Common situations: Hand-editing a matrix strategy block and using act's insert syntax incorrectly; treating an internal act extension syntax as a generic key; version drift where older workflows used the key differently.

Related errors


AI-assisted analysis of nektos/act@4f41128141 (2026-08-15). Data as JSON: /api/errors/3b3bfbd81f1a2a84. Report an issue: GitHub.