Shopify/liquid · error · Liquid::FloatDomainError

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

Error message

e.message (re-raised as Liquid::FloatDomainError from ::FloatDomainError in round)

What it means

The `round` filter wraps Ruby's ::FloatDomainError and re-raises it as Liquid::FloatDomainError. This occurs when rounding a value that is NaN or Infinity, which cannot be represented as a finite number. Liquid re-raises so templates fail with a domain-specific error rather than a raw Ruby one.

Solutions

  1. Validate the input is finite before rounding; avoid dividing floats by 0.0 upstream in the template.
  2. Rescue Liquid::FloatDomainError in your render error handler and render a placeholder.
  3. Re-order the pipeline so zero checks happen before any float division feeding round.
  4. Check the data source: JSON/API inputs may carry Infinity/NaN values that Liquid accepts then fails on.
  5. Sanitize values with a custom filter or preprocessing that replaces non-finite values with nil/default.

Example fix

// before
{{ 1 | divided_by: 0.0 | round: 2 }}
// after
{% if divisor != 0 %}{{ 1 | divided_by: divisor | round: 2 }}{% else %}0{% endif %}
Defensive patterns

Strategy: validation

Validate before calling

# before render
raise "non-finite value" unless value&.finite? || value.nil?

Type guard

def finite_number?(v)
  v.is_a?(Numeric) && v.to_f.finite?
end

Try / catch

begin
  template.render(assigns)
rescue Liquid::FloatDomainError => e
  render_placeholder
end

Prevention

When it happens

Trigger: `{{ value | round: 2 }}` where value is Float::INFINITY or Float::NAN (e.g. result of a prior 0.0 division), or `n` argument is non-numeric causing coercion anomalies.

Common situations: Pipelines like `{{ 1 | divided_by: 0.0 | round }}` where a float division by zero yields Infinity which then fails on round; scientific/financial templates with unvalidated computed values.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at lib/liquid/standardfilters.rb:895

      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

    # @liquid_public_docs
    # @liquid_type filter
    # @liquid_category math
    # @liquid_summary
    #   Rounds a number up to the nearest integer.
    # @liquid_syntax number | ceil
    # @liquid_return [number]
    def ceil(input)
      Utils.to_number(input).ceil.to_i
    rescue ::FloatDomainError => e
      raise Liquid::FloatDomainError, e.message
    end

    # @liquid_public_docs
    # @liquid_type filter
    # @liquid_category math

View on GitHub (pinned to 807d45a6b3)