Shopify/liquid · error · Liquid::ArgumentError

invalid integer

Error message

invalid integer

What it means

Utils.to_integer converts a value to an Integer; non-Integers are stringified and passed to Integer(), and if that fails (::ArgumentError) it raises Liquid::ArgumentError, 'invalid integer'. Used by tags/filters that require integral operands (e.g. loop limits, slice offsets).

Solutions

  1. Ensure the value is an Integer or a numeric string before passing it to tags/filters that need integers.
  2. Sanitize in the template with the default or plus filters, e.g. {{ limit | default: 10 | plus: 0 }}.
  3. Validate/cast user-supplied values in Ruby before adding them to assigns.

Example fix

// before
render(assigns.merge('limit' => params[:limit]))
// after
render(assigns.merge('limit' => Integer(params[:limit], 10) rescue 10))
Defensive patterns

Strategy: validation

Validate before calling

def ensure_integer(v)
  raise Liquid::ArgumentError, 'invalid integer' unless v.is_a?(Integer) || v.to_s.match?(/\A-?\d+\z/)
  v
end

Type guard

def integer_like?(v)
  v.is_a?(Integer) || (v.respond_to?(:to_s) && v.to_s.match?(/\A-?\d+\z/))
end

Try / catch

begin
  output = template.render(assigns)
rescue Liquid::ArgumentError => e
  raise unless e.message == 'invalid integer'
  assigns['limit'] = assigns['limit'].to_i.nonzero? || 10
  retry
end

Prevention

When it happens

Trigger: Passing a non-numeric string like 'abc', nil.to_s (''), '12abc', or a Float in a position where Utils.to_integer is called (e.g. slice/pagination parameters in tags).

Common situations: Template variables bound to user input that is not numeric; empty strings from unassigned variables; locale-formatted numbers ('1,000') that Integer() cannot parse.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at lib/liquid/utils.rb:47

        end

        if from <= index
          segments << item
        end

        index += 1
      end

      segments
    end

    def self.to_integer(num)
      return num if num.is_a?(Integer)
      num = num.to_s
      begin
        Integer(num)
      rescue ::ArgumentError
        raise Liquid::ArgumentError, "invalid integer"
      end
    end

    def self.to_number(obj)
      case obj
      when Float
        BigDecimal(obj.to_s)
      when Numeric
        obj
      when String
        DECIMAL_REGEX.match?(obj.strip) ? BigDecimal(obj) : obj.to_i
      else
        if obj.respond_to?(:to_number)
          obj.to_number
        else
          0
        end
      end

View on GitHub (pinned to 807d45a6b3)