mikefarah/yq · error
reduce must be given a block, got %v instead
Error message
reduce must be given a block, got %v instead
What it means
Along with a variable assignment on the left, `reduce` expects the right-hand side of its expression to be a block operation (the `(init; update)` body). This error fires when the RHS is some other operation type, meaning the reduce body was malformed or omitted. yq throws it because the block carries the accumulator initialiser and update expression.
Source
Thrown at pkg/yqlib/operator_reduce.go:21
import (
"container/list"
"fmt"
)
func reduceOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("reduceOp")
//.a as $var reduce (0; . + $var)
//lhs is the assignment operator
//rhs is the reduce block
// '.' refers to the current accumulator, initialised to 0
// $var references a single element from the .a
//ensure lhs is actually an assignment
//and rhs is a block (empty)
if expressionNode.LHS.Operation.OperationType != assignVariableOpType {
return Context{}, fmt.Errorf("reduce must be given a variables assignment, got %v instead", expressionNode.LHS.Operation.OperationType.Type)
} else if expressionNode.RHS.Operation.OperationType != blockOpType {
return Context{}, fmt.Errorf("reduce must be given a block, got %v instead", expressionNode.RHS.Operation.OperationType.Type)
}
arrayExpNode := expressionNode.LHS.LHS
array, err := d.GetMatchingNodes(context, arrayExpNode)
if err != nil {
return Context{}, err
}
variableName := expressionNode.LHS.RHS.Operation.StringValue
initExp := expressionNode.RHS.LHS
accum, err := d.GetMatchingNodes(context, initExp)
if err != nil {
return Context{}, err
}
View on GitHub (pinned to 8b5af0694b)
Solutions
- Supply the parenthesised block: `reduce .a[] as $x (0; . + $x)`.
- Make sure there is no pipe operator between `as $x` and the `(init; update)` block.
- Include both initialiser and update separated by `;` inside the parentheses.
- If you only need a sum/aggregation, verify reduce is the right operator versus `add` or `sum`.
Example fix
// before yq 'reduce .a[] as $x 0' file.yml // after yq 'reduce .a[] as $x (0; . + $x)' file.yml
Defensive patterns
Strategy: try-catch
Validate before calling
echo "$expr" | grep -Eq 'as \\$[a-zA-Z_]+ \\([^)]*;[^)]*\\)' || echo "reduce needs a (init; update) block"
Try / catch
out=$(yq "$expr" file.yml 2>&1) || { echo "$out"; case "$out" in *"must be given a block"*) echo "append the (init; update) block";; esac; } Prevention
- Always include the parenthesised (init; update) body after the variable.
- Do not insert a pipe between 'as $var' and the block.
- Keep both initialiser and update inside the parentheses separated by ';'.
- For simple aggregations, prefer add/sum over reduce.
When it happens
Trigger: Writing `reduce .a[] as $x 0` (no parenthesised body), or `reduce .a[] as $x; . + 1` where a pipe splits off what should be the block, or any typo that prevents the `(init; update)` block from parsing as the RHS.
Common situations: Missing parentheses around the init/update pair; accidentally inserting a `|` between the variable and the block; hand-converted jq one-liners where the semicolon body got separated.
Related errors
- reduce must be given a variables assignment, got %v instead
- no support for input format
- aborted
- unrecognised type :( %v
- orderedMap: invalid yaml node
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/bb7a0b4c8b03014f.
Report an issue: GitHub.