mikefarah/yq · error
system operator: command must be a non-empty string
Error message
system operator: command must be a non-empty string
What it means
The `system` operator rejects an empty-string command. After confirming the command node is a string scalar, resolveCommandNode checks that it is non-empty; an empty string cannot name a program to execute and is treated as an error rather than a no-op.
Source
Thrown at pkg/yqlib/operator_system.go:56
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")
}
return cmdNode.Value, nil
}
func systemOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
if !ConfiguredSecurityPreferences.EnableSystemOps {
return Context{}, fmt.Errorf("system operations are disabled, use --security-enable-system-operator to enable")
}
// determine at parse time whether we have (command; args) or just (command)
hasArgs := expressionNode.RHS.Operation.OperationType == blockOpType
var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
nodeContext := context.SingleReadonlyChildContext(candidate)
View on GitHub (pinned to 8b5af0694b)
Solutions
- Supply a default command: `system(.cmd // "echo")` so empty resolves to a valid command
- Guard before running: only evaluate system when the command is non-empty, e.g. wrap in an if: `select(.cmd != "") | system(.cmd)`
- Fix the input document so the command field contains the actual program name
Example fix
// before: .cmd is "" in the document system(.cmd) // after: guard against empty select(.cmd != "" and .cmd != null) | system(.cmd)
Defensive patterns
Strategy: validation
Validate before calling
// skip empty commands select(.cmd != null and .cmd != "") | system(.cmd)
Prevention
- Default empty fields: .cmd // "echo"
- Validate input documents for unset/empty command fields before running system()
- In CI, ensure env-substituted placeholders are populated
When it happens
Trigger: The command field exists in the YAML but is empty, e.g. `cmd: ""` or `cmd:` with no value resolved to an empty scalar, then `system(.cmd)` is evaluated.
Common situations: Unset config values in CI pipelines (empty env-derived placeholders), template-rendered files where the command was substituted with an empty string, or optional fields defaulted to "".
Related errors
- expected to find one 'value' entry but found %v in position
- cannot repeat string by a negative number (%v)
- system operator: argument must be a non-null scalar; got kin
- system operator: args must be a non-null scalar or sequence
- system operator: command expression returned no results
AI-assisted analysis of mikefarah/yq@8b5af0694b (2026-09-05).
Data as JSON: /api/errors/18e6691b0cfabc2f.
Report an issue: GitHub.