Shopify/liquid · error · Liquid::ZeroDivisionError

e.message (re-raised as Liquid::ZeroDivisionError from…

Error message

e.message (re-raised as Liquid::ZeroDivisionError from ::ZeroDivisionError in modulo)

What it means

The `modulo` filter wraps Ruby's ::ZeroDivisionError and re-raises it as Liquid::ZeroDivisionError. It occurs when the right-hand operand of the modulo operation is 0. Liquid normalizes the native error into its own exception class for template-level handling.

Solutions

  1. Check the modulus value in the template: `{% if step != 0 %}{{ n | modulo: step }}{% endif %}`.
  2. Assign a non-zero fallback before the filter: `{% assign step = step | default: 1 %}` (and ensure it is not literal 0).
  3. Fix upstream data so the modulus count is always a positive integer.
  4. Rescue Liquid::ZeroDivisionError in the rendering error handler and provide a default result.
  5. Verify string-to-number coercion: an empty string or nil operand coerces to 0 and triggers the error.

Example fix

// before
{{ index | modulo: step }}
// after
{% if step > 0 %}{{ index | modulo: step }}{% else %}{{ index }}{% endif %}
Defensive patterns

Strategy: try-catch

Validate before calling

{% if step and step > 0 %}{{ index | modulo: step }}{% else %}{{ index }}{% endif %}

Type guard

def positive_nonzero_int?(v)
  v.is_a?(Numeric) && v > 0
end

Try / catch

begin
  template.render(assigns)
rescue Liquid::ZeroDivisionError => e
  default_striping_output
end

Prevention

When it happens

Trigger: Using `{{ 10 | modulo: 0 }}` or `{{ n | modulo: divisor }}` where the divisor variable is 0 or coerces to 0 via Utils.to_number.

Common situations: Alternating-row striping (`cycle`-like logic) or pagination calculations where the modulus count variable is unset, empty, or computed as 0.

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/acdb6403449726e8. Report an issue: GitHub.

Appendix: source

Thrown at lib/liquid/standardfilters.rb:879

    # @liquid_syntax number | divided_by: number
    # @liquid_return [number]
    def divided_by(input, operand)
      apply_operation(input, operand, :/)
    rescue ::ZeroDivisionError => e
      raise Liquid::ZeroDivisionError, e.message
    end

    # @liquid_public_docs
    # @liquid_type filter
    # @liquid_category math
    # @liquid_summary
    #   Returns the remainder of dividing a number by a given number.
    # @liquid_syntax number | modulo: number
    # @liquid_return [number]
    def modulo(input, operand)
      apply_operation(input, operand, :%)
    rescue ::ZeroDivisionError => e
      raise Liquid::ZeroDivisionError, e.message
    end

    # @liquid_public_docs
    # @liquid_type filter
    # @liquid_category math
    # @liquid_summary
    #   Rounds a number to the nearest integer.
    # @liquid_syntax number | round
    # @liquid_return [number]
    def round(input, n = 0)
      result = Utils.to_number(input).round(Utils.to_number(n))
      result = result.to_f if result.is_a?(BigDecimal)
      result = result.to_i if n == 0
      result
    rescue ::FloatDomainError => e
      raise Liquid::FloatDomainError, e.message
    end

View on GitHub (pinned to 807d45a6b3)