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
- Validate the value is finite before flooring; fix any upstream division by 0.0.
- Guard with a template conditional before applying floor.
- Rescue Liquid::FloatDomainError in render error handling and render a fallback value.
- Sanitize incoming JSON/API data so Infinity/NaN never reach the template context.
- 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
- Ensure values reaching floor are finite numbers
- Avoid divided_by: 0.0 in pipelines feeding floor
- Sanitize non-finite values from remote data sources
- Prefer integer divided_by when a floored integer is the goal
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
- e.message (re-raised as Liquid::FloatDomainError from…
- e.message (re-raised as Liquid::FloatDomainError from…
- e.message (re-raised as Liquid::ZeroDivisionError from…
- e.message (re-raised as Liquid::ZeroDivisionError from…
- undefined filter #
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_docsView on GitHub (pinned to 807d45a6b3)