mikefarah/yq · error

system operator: args must be a non-null scalar or sequence

Error message

system operator: args must be a non-null scalar or sequence of non-null scalars; got kind=%v tag=%v

What it means

The yq `system` operator's args expression must yield either a single non-null scalar or a sequence of non-null scalars. resolveSystemArgs throws this when the single args node is a map or sequence-of-sequences (anything that is not a ScalarNode). A null args node is tolerated (treated as no args), but other non-scalars are rejected.

Source

Thrown at pkg/yqlib/operator_system.go:39

				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
}

func resolveCommandNode(commandNodes Context) (string, error) {
	if commandNodes.MatchingNodes.Front() == nil {
		return "", fmt.Errorf("system operator: command expression returned no results")
	}
	if commandNodes.MatchingNodes.Len() > 1 {
		log.Debugf("system operator: command expression returned %d results, using first", commandNodes.MatchingNodes.Len())
	}
	cmdNode := commandNodes.MatchingNodes.Front().Value.(*CandidateNode)
	if cmdNode.Kind != ScalarNode || cmdNode.guessTagFromCustomType() != "!!str" {
		return "", fmt.Errorf("system operator: command must be a string scalar")
	}
	if cmdNode.Value == "" {
		return "", fmt.Errorf("system operator: command must be a non-empty string")
	}

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Point the args expression at a scalar, e.g. `system("cmd"; .name)` instead of `system("cmd"; .)`
  2. If the args are in a map, extract the fields you need into a flat sequence: `system("cmd"; [.config.host, .config.port])`
  3. Coerce values to strings with tostring() if they are complex and you want their text form

Example fix

// before: passing a whole map as args
system("curl"; .request)
// after: pass a flat sequence of scalars
system("curl"; [.request.url, .request.method])
Defensive patterns

Strategy: validation

Validate before calling

// ensure args node is scalar or flat sequence of scalars
system("curl"; (if (.args | tag) == "!!seq" then [.args[] | tostring] else [.args | tostring] end))

Prevention

When it happens

Trigger: Calling `system("cmd"; .config)` where `.config` is a map, or `system("cmd"; .list[0].nested)` where the resolved node is a mapping, so the args node has kind MapNode or SequenceNode at the top level.

Common situations: Pointing the args expression at a YAML object by mistake, expecting it to be spread into arguments, or forgetting an array index so a whole sequence-of-objects is resolved instead of a scalar.

Related errors


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