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
- Coerce to string before splitting: '.a |= ("\(. )" | split(","))' or use the string interpolation operator.
- Quote the value at the source so YAML parses it as a string (e.g. version: "1.2.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
- Coerce with string interpolation '\\(.)' before splitting values that may be typed.
- Quote scalars in source YAML when they will be split (versions, IPs, CSV-ish fields).
- Remember nulls are skipped silently — check for them if output array is unexpectedly empty.
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
- strings cannot be subtracted
- %v (%v) cannot be subtracted from %v
- %v cannot check contained in %v
- from entries only runs against arrays
- cannot substitute with %v, can only substitute strings. Hint
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/9a3ef3913b43e760.
Report an issue: GitHub.