mikefarah/yq · error

maps not yet supported for comparison

Error message

maps not yet supported for comparison

What it means

The comparison operators (<, <=, >, >= in yq) only support scalar operands. When the LEFT-hand side of a comparison is a map (MappingNode), yq has no defined ordering for maps and returns this error instead of guessing. It is a deliberate 'not yet supported' limitation of the comparator implementation.

Source

Thrown at pkg/yqlib/operator_compare.go:36

}

func compare(prefs compareTypePref) func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
	return func(_ *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
		log.Debugf("compare cross function")
		if lhs == nil && rhs == nil {
			owner := &CandidateNode{}
			return createBooleanCandidate(owner, prefs.OrEqual), nil
		} else if lhs == nil {
			log.Debugf("lhs nil, but rhs is not")
			return createBooleanCandidate(rhs, false), nil
		} else if rhs == nil {
			log.Debugf("rhs nil, but rhs is not")
			return createBooleanCandidate(lhs, false), nil
		}

		switch lhs.Kind {
		case MappingNode:
			return nil, fmt.Errorf("maps not yet supported for comparison")
		case SequenceNode:
			return nil, fmt.Errorf("arrays not yet supported for comparison")
		default:
			if rhs.Kind != ScalarNode {
				return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhs.Tag)
			}
			target := lhs.CopyWithoutContent()
			boolV, err := compareScalars(context, prefs, lhs, rhs)

			return createBooleanCandidate(target, boolV), err
		}
	}
}

func compareDateTime(layout string, prefs compareTypePref, lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
	lhsTime, err := parseDateTime(layout, lhs.Value)
	if err != nil {
		return false, err

View on GitHub (pinned to 8b5af0694b)

Solutions

  1. Navigate to the scalar inside the map before comparing, e.g. `.config.size > 3` instead of `.config > 3`.
  2. If you must order maps, sort by a specific key: `sort_by(.name)` rather than comparing whole maps.
  3. Use equality (==) which supports maps, if ordering is not actually needed.
  4. Split the comparison: extract the scalar with a separate expression, then compare.

Example fix

# before
yq '.metadata > 2' file.yaml   # metadata is a map
# after
yq '.metadata.replicas > 2' file.yaml
Defensive patterns

Strategy: type-guard

Validate before calling

# ensure the lhs is a scalar before comparing:
yq -e '.config | type == "!!scalar"' file.yaml || echo "lhs is not a scalar"

Type guard

// yq expression guard: select only scalar lhs before comparing
// yq '.[] | select(tag == "!!int" or tag == "!!float" or tag == "!!str") | . > 3' file.yaml

Prevention

When it happens

Trigger: Any yq expression using <, <=, >, or >= where the lhs evaluates to a mapping node, e.g. `yq '.config > 3' file.yaml` where `.config` is a map, or `sort_by`/`min`/`max` over a sequence of maps where the comparator receives a whole map as the lhs.

Common situations: Pointing a comparison at the wrong key (comparing a nested object instead of the scalar inside it); calling sort_by(...) with a path that resolves to a map; using min/max over documents that are maps rather than scalar arrays; schema drift where a field that used to be a number became a nested object.

Related errors


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