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
- 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.
- Use the standard matrix include syntax (strategy.matrix.include as a list) instead of the insert directive if you do not need it.
- 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
- Treat the insert directive as advanced syntax; prefer standard matrix.include.
- Run act --verbose on a tiny workflow when matrix interpolation fails, to locate the node.
- Indent insert values as a block map.
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
- ErrShortRef
- invalid Step %v: missing run or uses key
- expressions are not allowed here
- %sFailed to parse: %s
- %sExpected a scalar got %v
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/3b3bfbd81f1a2a84.
Report an issue: GitHub.