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 floor)

What it means

The `floor` filter wraps Ruby's ::FloatDomainError and re-raises it as Liquid::FloatDomainError. It is raised when the input is NaN or Infinity, which have no integer floor. Liquid re-raises under its own exception class for uniform template error handling.

Solutions

  1. Validate the value is finite before flooring; fix any upstream division by 0.0.
  2. Guard with a template conditional before applying floor.
  3. Rescue Liquid::FloatDomainError in render error handling and render a fallback value.
  4. Sanitize incoming JSON/API data so Infinity/NaN never reach the template context.
  5. Prefer integer division (`divided_by` with integers) when a floor-like result is desired, avoiding floats entirely.

Example fix

// before
{{ ratio | floor }}
// after
{% if ratio == ratio %}{{ ratio | floor }}{% else %}0{% endif %}
Defensive patterns

Strategy: validation

Validate before calling

# before render
raise "non-finite input for floor" unless input.nil? || input.to_f.finite?

Type guard

def floor_safe(v)
  v.is_a?(Numeric) && v.to_f.finite? ? v.to_f.floor : 0
end

Try / catch

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

Prevention

When it happens

Trigger: `{{ value | floor }}` where value is Float::INFINITY or Float::NAN, e.g. resulting from `divided_by: 0.0` earlier in the pipeline or from a non-finite data value.

Common situations: Templates computing floors of ratios or averages (e.g. bytes-to-KB conversions, progress percentages) where the denominator can be float zero or data contains non-finite numbers.

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

Appendix: source

Thrown at lib/liquid/standardfilters.rb:921

    # @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
    # @liquid_summary
    #   Rounds a number down to the nearest integer.
    # @liquid_syntax number | floor
    # @liquid_return [number]
    def floor(input)
      Utils.to_number(input).floor.to_i
    rescue ::FloatDomainError => e
      raise Liquid::FloatDomainError, e.message
    end

    # @liquid_public_docs
    # @liquid_type filter
    # @liquid_category math
    # @liquid_summary
    #   Limits a number to a minimum value.
    # @liquid_syntax number | at_least
    # @liquid_return [number]
    def at_least(input, n)
      min_value = Utils.to_number(n)

      result = Utils.to_number(input)
      result = min_value if min_value > result
      result.is_a?(BigDecimal) ? result.to_f : result
    end

    # @liquid_public_docs

View on GitHub (pinned to 807d45a6b3)