mikefarah/yq · error

%v: expected either a !!str or !!int in the path, found %v i

Error message

%v: expected either a !!str or !!int in the path, found %v instead

What it means

Every element of a SETPATH/DELPATHS path array must be either a string (map key) or an int (array index). getPathArrayFromNode throws this error, prefixed with the operator name, when an element has any other tag — typically !!float, !!bool, !!null, or !!map/!!seq elements nested inside a path array.

Source

Thrown at pkg/yqlib/operator_path.go:35

func getPathArrayFromNode(funcName string, node *CandidateNode) ([]interface{}, error) {
	if node.Kind != SequenceNode {
		return nil, fmt.Errorf("%v: expected path array, but got %v instead", funcName, node.Tag)
	}

	path := make([]interface{}, len(node.Content))

	for i, childNode := range node.Content {
		switch childNode.Tag {
		case "!!str":
			path[i] = childNode.Value
		case "!!int":
			number, err := parseInt(childNode.Value)
			if err != nil {
				return nil, fmt.Errorf("%v: could not parse %v as an int: %w", funcName, childNode.Value, err)
			}
			path[i] = number
		default:
			return nil, fmt.Errorf("%v: expected either a !!str or !!int in the path, found %v instead", funcName, childNode.Tag)
		}

	}
	return path, nil
}

// SETPATH(pathArray; value)
func setPathOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
	log.Debugf("SetPath")

	if expressionNode.RHS.Operation.OperationType != blockOpType {
		return Context{}, fmt.Errorf("SETPATH must be given a block (;), got %v instead", expressionNode.RHS.Operation.OperationType.Type)
	}

	lhsPathContext, err := d.GetMatchingNodes(context.ReadOnlyClone(), expressionNode.RHS.LHS)

	if err != nil {
		return Context{}, err

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Convert float indices to ints: '(.idx | floor | tonumber)' or fix division to integer arithmetic
  2. Coerce non-string keys to strings: '(.k | tostring)' inside the path array
  3. Ensure the path array contains only string keys and int indices, e.g. 'SETPATH(["a", 0]; v)'

Example fix

// before
yq 'SETPATH([.i / 2]; "x")' f.yml   // 1/2 -> 0.5 !!float
// after
yq 'SETPATH([.i / 2 | floor]; "x")' f.yml
Defensive patterns

Strategy: validation

Validate before calling

yq '[.path[] | tag] | all(. == "!!str" or . == "!!int")' f.yml  # must be true

Type guard

yq 'select([.path[] | tag] | all(. == "!!str" or . == "!!int"))' f.yml

Try / catch

// shell
out=$(yq 'SETPATH([.i / 2]; v)' f.yml 2>&1) || { echo "bad path element: $out"; exit 1; }

Prevention

When it happens

Trigger: 'SETPATH([1.5]; v)' (float index), 'SETPATH([true]; v)', 'SETPATH([null]; v)', 'DELPATHS([["a", ["b"]]])' (nested array as path element), or a path expression yielding map entries.

Common situations: Computed indices producing floats (division), keys that are null because the document lacks expected fields, accidentally passing data structures as paths instead of key strings, jq-style paths copied over that use floats.

Related errors


AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05). Data as JSON: /api/errors/d6431322579e6ecb. Report an issue: GitHub.