{"record":{"id":"acdb6403449726e8","repo":"Shopify/liquid","slug":"e-message-re-raised-as-liquid-zerodivisionerror-acdb64","errorCode":null,"errorMessage":"e.message (re-raised as Liquid::ZeroDivisionError from ::ZeroDivisionError in modulo)","messagePattern":"e\\.message \\(re-raised as Liquid::ZeroDivisionError from ::ZeroDivisionError in modulo\\)","errorType":"exception","errorClass":"Liquid::ZeroDivisionError","httpStatus":null,"severity":"error","filePath":"lib/liquid/standardfilters.rb","lineNumber":879,"sourceCode":"    # @liquid_syntax number | divided_by: number\n    # @liquid_return [number]\n    def divided_by(input, operand)\n      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    #   Returns the remainder of dividing a number by a given number.\n    # @liquid_syntax number | modulo: number\n    # @liquid_return [number]\n    def modulo(input, operand)\n      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","sourceCodeStart":861,"sourceCodeEnd":897,"githubUrl":"https://github.com/Shopify/liquid/blob/807d45a6b3d4568e64e86b375e3702df2c7c860c/lib/liquid/standardfilters.rb#L861-L897","documentation":"The `modulo` filter wraps Ruby's ::ZeroDivisionError and re-raises it as Liquid::ZeroDivisionError. It occurs when the right-hand operand of the modulo operation is 0. Liquid normalizes the native error into its own exception class for template-level handling.","triggerScenarios":"Using `{{ 10 | modulo: 0 }}` or `{{ n | modulo: divisor }}` where the divisor variable is 0 or coerces to 0 via Utils.to_number.","commonSituations":"Alternating-row striping (`cycle`-like logic) or pagination calculations where the modulus count variable is unset, empty, or computed as 0.","solutions":["Check the modulus value in the template: `{% if step != 0 %}{{ n | modulo: step }}{% endif %}`.","Assign a non-zero fallback before the filter: `{% assign step = step | default: 1 %}` (and ensure it is not literal 0).","Fix upstream data so the modulus count is always a positive integer.","Rescue Liquid::ZeroDivisionError in the rendering error handler and provide a default result.","Verify string-to-number coercion: an empty string or nil operand coerces to 0 and triggers the error."],"exampleFix":"// before\n{{ index | modulo: step }}\n// after\n{% if step > 0 %}{{ index | modulo: step }}{% else %}{{ index }}{% endif %}","handlingStrategy":"try-catch","validationCode":"{% if step and step > 0 %}{{ index | modulo: step }}{% else %}{{ index }}{% endif %}","typeGuard":"def positive_nonzero_int?(v)\n  v.is_a?(Numeric) && v > 0\nend","tryCatchPattern":"begin\n  template.render(assigns)\nrescue Liquid::ZeroDivisionError => e\n  default_striping_output\nend","preventionTips":["Guarantee modulus variables are positive integers before render","Never bind nil/empty values into variables used as moduli","Rescue Liquid::ZeroDivisionError centrally in the render pipeline","Test alternating-row/pagination templates with step=0"],"tags":["liquid","math","division-by-zero","template"],"backgroundTag":"invalid-argument-value","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"}