{"record":{"id":"9f6d3ecd451598e5","repo":"Shopify/liquid","slug":"e-message-re-raised-as-liquid-floatdomainerror-f-9f6d3e","errorCode":null,"errorMessage":"e.message (re-raised as Liquid::FloatDomainError from ::FloatDomainError in floor)","messagePattern":"e\\.message \\(re-raised as Liquid::FloatDomainError from ::FloatDomainError in floor\\)","errorType":"exception","errorClass":"Liquid::FloatDomainError","httpStatus":null,"severity":"error","filePath":"lib/liquid/standardfilters.rb","lineNumber":921,"sourceCode":"    # @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\n    # @liquid_summary\n    #   Rounds a number down to the nearest integer.\n    # @liquid_syntax number | floor\n    # @liquid_return [number]\n    def floor(input)\n      Utils.to_number(input).floor.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\n    # @liquid_summary\n    #   Limits a number to a minimum value.\n    # @liquid_syntax number | at_least\n    # @liquid_return [number]\n    def at_least(input, n)\n      min_value = Utils.to_number(n)\n\n      result = Utils.to_number(input)\n      result = min_value if min_value > result\n      result.is_a?(BigDecimal) ? result.to_f : result\n    end\n\n    # @liquid_public_docs","sourceCodeStart":903,"sourceCodeEnd":939,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/standardfilters.rb#L903-L939","documentation":"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.","triggerScenarios":"`{{ 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.","commonSituations":"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.","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."],"exampleFix":"// before\n{{ ratio | floor }}\n// after\n{% if ratio == ratio %}{{ ratio | floor }}{% else %}0{% endif %}","handlingStrategy":"validation","validationCode":"# before render\nraise \"non-finite input for floor\" unless input.nil? || input.to_f.finite?","typeGuard":"def floor_safe(v)\n  v.is_a?(Numeric) && v.to_f.finite? ? v.to_f.floor : 0\nend","tryCatchPattern":"begin\n  template.render(assigns)\nrescue Liquid::FloatDomainError => e\n  render_zero_fallback\nend","preventionTips":["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"],"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"}