mikefarah/yq · error

cannot split %v, can only split strings

Error message

cannot split %v, can only split strings

What it means

The split operator ('split(sep)') in operator_strings.go only splits string nodes into arrays. Nodes tagged '!!null' are silently skipped, but any other non-string tag (int, bool, map, sequence) triggers this error, reporting the offending tag.

Source

Thrown at pkg/yqlib/operator_strings.go:552

	rhs, err := d.GetMatchingNodes(context.ReadOnlyClone(), expressionNode.RHS)
	if err != nil {
		return Context{}, err
	}
	if rhs.MatchingNodes.Front() != nil {
		splitStr = rhs.MatchingNodes.Front().Value.(*CandidateNode).Value
	}

	var results = list.New()

	for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
		node := el.Value.(*CandidateNode)
		if node.Tag == "!!null" {
			continue
		}

		if node.guessTagFromCustomType() != "!!str" {
			return Context{}, fmt.Errorf("cannot split %v, can only split strings", node.Tag)
		}
		kind, tag, content := split(node.Value, splitStr)
		result := node.CreateReplacement(kind, tag, "")
		result.AddChildren(content)
		results.PushBack(result)
	}

	return context.ChildContext(results), nil
}

func split(value string, spltStr string) (Kind, string, []*CandidateNode) {
	var contents []*CandidateNode

	if value != "" {
		log.Debugf("going to spltStr[%v]", spltStr)
		var newStrings = strings.Split(value, spltStr)
		contents = make([]*CandidateNode, len(newStrings))

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Coerce to string before splitting: '.a |= ("\(. )" | split(","))' or use the string interpolation operator.
  2. Quote the value at the source so YAML parses it as a string (e.g. version: "1.2.3").
  3. Skip/filter non-string nodes first: 'select(tag == "!!str") | split(",")'.

Example fix

// before (fails: .version parsed as something non-string)
yq '.version | split(".")' chart.yaml

// after
yq '.version |= ("\(. )" | split("."))' chart.yaml
Defensive patterns

Strategy: type-guard

Validate before calling

yq '.a | tag' file.yaml   # must be '!!str' before split
// script check:
TAG=$(yq '.a | tag' file.yaml); [ "$TAG" = "!!str" ] || echo "split requires a string, got $TAG"

Type guard

// in yq expression: select(tag == "!!str") | split(",")
function isStringNode(node) { return node && node.tag === '!!str'; }

Try / catch

out=$(yq '.a | split(",")' file.yaml 2>&1) || { echo "split failed: $out"; out="$(yq '.a | ("\\(.)" | split(","))' file.yaml)"; }

Prevention

When it happens

Trigger: Running '.a | split(",")' where .a is a number (e.g. 1234), boolean, array, or map; splitting a value read from YAML/JSON that YAML auto-typed to non-string; piping the result of a numeric expression like '.port | split(".")'.

Common situations: IPs/versions stored unquoted (192.168.0.1 parses as structure or string depending on quoting), so split fails on typed nodes; splitting numeric IDs; applying a string-split expression to a heterogeneous set of documents where some fields are null or numeric.

Related errors


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