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
- Validate the input is finite before rounding; avoid dividing floats by 0.0 upstream in the template.
- Rescue Liquid::FloatDomainError in your render error handler and render a placeholder.
- Re-order the pipeline so zero checks happen before any float division feeding round.
- Check the data source: JSON/API inputs may carry Infinity/NaN values that Liquid accepts then fails on.
- 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
- Avoid float division by 0.0 upstream in template pipelines
- Sanitize JSON/API inputs rejecting Infinity/NaN
- Run strict render error reporting in staging to catch NaN early
- Prefer integer math when decimals are unnecessary
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
- 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/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 mathView on GitHub (pinned to 807d45a6b3)