Shopify/liquid · error · Liquid::ArgumentError

cannot sort values of incompatible types

Error message

cannot sort values of incompatible types

What it means

`nil_safe_compare` raises Liquid::ArgumentError "cannot sort values of incompatible types" when `sort` encounters two non-nil values that cannot be compared (e.g. a String vs an Integer). Ruby's `<=>` returns nil for such pairs, and Liquid surfaces this as a clear argument error rather than an opaque comparison failure.

Solutions

  1. Normalize the field to one type before sorting (e.g. convert all values to strings, or all to numbers).
  2. Pre-process in code: coerce the collection's values to a uniform type before passing to the template.
  3. Use `sort_natural` if case-insensitive string comparison of stringified values is acceptable.
  4. Rescue Liquid::ArgumentError in the render error handler and fall back to unsorted rendering.
  5. Fix upstream serialization so numeric fields are always numeric (e.g. consistent JSON typing).

Example fix

// before
{{ items | sort: 'price' }}
// after
// normalize in Ruby before render: items.each { |i| i['price'] = i['price'].to_i }
{{ items | sort: 'price' }}
Defensive patterns

Strategy: validation

Validate before calling

# before render
raise "mixed types in 'price'" if array.map { |i| i['price'].class }.uniq.size > 1

Type guard

def uniformly_typed?(arr, prop)
  arr.map { |i| i[prop].class }.uniq.size <= 1
end

Try / catch

begin
  template.render(assigns)
rescue Liquid::ArgumentError => e
  render_unsorted_fallback
end

Prevention

When it happens

Trigger: `{{ array | sort: 'key' }}` or `{{ array | sort }}` where the collection (or the values at the given property) mixes types — e.g. some items have Integer prices and others String prices.

Common situations: Merged data from different sources with inconsistent field types; JSON numbers serialized as strings in some records; user-supplied input bound into the array; nil coexisting with mixed typed values after record updates.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of Shopify/liquid@807d45a6b3 (2026-09-08). Data as JSON: /api/errors/a58ac6bbd60da452. Report an issue: GitHub.

Appendix: source

Thrown at lib/liquid/standardfilters.rb:1044

      raise Liquid::ArgumentError, "cannot select the property '#{Utils.to_s(property)}'"
    end

    def apply_operation(input, operand, operation)
      result = Utils.to_number(input).send(operation, Utils.to_number(operand))
      result.is_a?(BigDecimal) ? result.to_f : result
    end

    def nil_safe_compare(a, b)
      result = a <=> b

      if result
        result
      elsif a.nil?
        1
      elsif b.nil?
        -1
      else
        raise Liquid::ArgumentError, "cannot sort values of incompatible types"
      end
    end

    def nil_safe_casecmp(a, b)
      if !a.nil? && !b.nil?
        a.to_s.casecmp(b.to_s)
      elsif a.nil? && b.nil?
        0
      else
        a.nil? ? 1 : -1
      end
    end

    class InputIterator
      include Enumerable

      def initialize(input, context)
        @context = context

View on GitHub (pinned to 807d45a6b3)