{"record":{"id":"a4be8c1b01a50471","repo":"Shopify/liquid","slug":"e-message-re-raised-as-liquid-floatdomainerror-f","errorCode":null,"errorMessage":"e.message (re-raised as Liquid::FloatDomainError from ::FloatDomainError in round)","messagePattern":"e\\.message \\(re-raised as Liquid::FloatDomainError from ::FloatDomainError in round\\)","errorType":"exception","errorClass":"Liquid::FloatDomainError","httpStatus":null,"severity":"error","filePath":"lib/liquid/standardfilters.rb","lineNumber":895,"sourceCode":"      apply_operation(input, operand, :%)\n    rescue ::ZeroDivisionError => e\n      raise Liquid::ZeroDivisionError, e.message\n    end\n\n    # @liquid_public_docs\n    # @liquid_type filter\n    # @liquid_category math\n    # @liquid_summary\n    #   Rounds a number to the nearest integer.\n    # @liquid_syntax number | round\n    # @liquid_return [number]\n    def round(input, n = 0)\n      result = Utils.to_number(input).round(Utils.to_number(n))\n      result = result.to_f if result.is_a?(BigDecimal)\n      result = result.to_i if n == 0\n      result\n    rescue ::FloatDomainError => e\n      raise Liquid::FloatDomainError, e.message\n    end\n\n    # @liquid_public_docs\n    # @liquid_type filter\n    # @liquid_category math\n    # @liquid_summary\n    #   Rounds a number up to the nearest integer.\n    # @liquid_syntax number | ceil\n    # @liquid_return [number]\n    def ceil(input)\n      Utils.to_number(input).ceil.to_i\n    rescue ::FloatDomainError => e\n      raise Liquid::FloatDomainError, e.message\n    end\n\n    # @liquid_public_docs\n    # @liquid_type filter\n    # @liquid_category math","sourceCodeStart":877,"sourceCodeEnd":913,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/standardfilters.rb#L877-L913","documentation":"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.","triggerScenarios":"`{{ 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.","commonSituations":"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.","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."],"exampleFix":"// before\n{{ 1 | divided_by: 0.0 | round: 2 }}\n// after\n{% if divisor != 0 %}{{ 1 | divided_by: divisor | round: 2 }}{% else %}0{% endif %}","handlingStrategy":"validation","validationCode":"# before render\nraise \"non-finite value\" unless value&.finite? || value.nil?","typeGuard":"def finite_number?(v)\n  v.is_a?(Numeric) && v.to_f.finite?\nend","tryCatchPattern":"begin\n  template.render(assigns)\nrescue Liquid::FloatDomainError => e\n  render_placeholder\nend","preventionTips":["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"],"tags":["liquid","math","float","infinity","template"],"backgroundTag":"value-out-of-range","analyzedSha":"807d45a6b3d4568e64e86b375e3702df2c7c860c","analyzedAt":"2026-09-08T11:31:38.917Z","contentChangedAt":"2026-09-08T11:31:38.917Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}