mikefarah/yq · error

system operator: argument must be a non-null scalar; got kin

Error message

system operator: argument must be a non-null scalar; got kind=%v tag=%v

What it means

The yq `system` operator runs an external command; its arguments must each be a plain, non-null scalar. This error is thrown by resolveSystemArgs when an element of the args sequence is a map, sequence, or a null scalar. It aborts evaluation before any command is executed.

Source

Thrown at pkg/yqlib/operator_system.go:24

	"fmt"
	"os/exec"
	"strings"
)

func resolveSystemArgs(argsNode *CandidateNode) ([]string, error) {
	if argsNode == nil {
		return nil, nil
	}

	if argsNode.Kind == SequenceNode {
		args := make([]string, 0, len(argsNode.Content))
		for _, child := range argsNode.Content {
			// Only non-null scalar children are valid arguments.
			if child == nil {
				continue
			}
			if child.Kind != ScalarNode || child.Tag == "!!null" {
				return nil, fmt.Errorf("system operator: argument must be a non-null scalar; got kind=%v tag=%v", child.Kind, child.Tag)
			}
			args = append(args, child.Value)
		}
		if len(args) == 0 {
			return nil, nil
		}
		return args, nil
	}

	// Single-argument case: only accept a non-null scalar node.
	if argsNode.Tag == "!!null" {
		return nil, nil
	}
	if argsNode.Kind != ScalarNode {
		return nil, fmt.Errorf("system operator: args must be a non-null scalar or sequence of non-null scalars; got kind=%v tag=%v", argsNode.Kind, argsNode.Tag)
	}
	return []string{argsNode.Value}, nil
}

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Inspect the args sequence and remove or filter null/nested entries before passing to system, e.g. `[.[] | select(. != null)]`
  2. Ensure each argument is a string/int/bool scalar: quote values in the source YAML if they were being parsed as maps or sequences
  3. Dynamically build args with map(...) to coerce each element to a scalar string

Example fix

// before: args contains a null entry
system("echo"; [.a, .b])   # .b is null -> error
// after: filter nulls first
system("echo"; [.a, .b] | map(select(. != null)))
Defensive patterns

Strategy: validation

Validate before calling

// validate args sequence before system()
def cleanArgs: map(select(tag != "!!null" and (tag == "!!str" or tag == "!!int" or tag == "!!float" or tag == "!!bool")));
system("echo"; ([.a, .b] | cleanArgs))

Prevention

When it happens

Trigger: Using `system("cmd"; $args)` where the args expression resolves to a sequence containing a nested sequence or map (e.g. an array of arrays), or an explicit null item like `system("echo"; ["a", null, "b"])`.

Common situations: Building argument arrays programmatically with entries defaulted to null (e.g. from optional config keys or `.x // null`), or accidentally passing a nested structure because the args path matched the wrong node.

Related errors


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