{"id":"a38706a58b923e7e","repo":"gohugoio/hugo","slug":"the-number-can-t-be-divided-by-zero-at-modulo-oper","errorCode":null,"errorMessage":"the number can't be divided by zero at modulo operation","messagePattern":"the number can't be divided by zero at modulo operation","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/math/math.go","lineNumber":170,"sourceCode":"\treturn math.MaxInt64\n}\n\n// Min returns the smaller of all numbers in inputs. Any slices in inputs are flattened.\nfunc (ns *Namespace) Min(inputs ...any) (minimum float64, err error) {\n\treturn ns.applyOpToScalarsOrSlices(\"Min\", math.Min, inputs...)\n}\n\n// Mod returns n1 % n2.\nfunc (ns *Namespace) Mod(n1, n2 any) (int64, error) {\n\tai, erra := cast.ToInt64E(n1)\n\tbi, errb := cast.ToInt64E(n2)\n\n\tif erra != nil || errb != nil {\n\t\treturn 0, errors.New(\"modulo operator can't be used with non integer value\")\n\t}\n\n\tif bi == 0 {\n\t\treturn 0, errors.New(\"the number can't be divided by zero at modulo operation\")\n\t}\n\n\treturn ai % bi, nil\n}\n\n// ModBool returns the boolean of n1 % n2.  If n1 % n2 == 0, return true.\nfunc (ns *Namespace) ModBool(n1, n2 any) (bool, error) {\n\tres, err := ns.Mod(n1, n2)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\treturn res == int64(0), nil\n}\n\n// Mul multiplies the multivalued numbers n1 and n2 or more values.\nfunc (ns *Namespace) Mul(inputs ...any) (any, error) {\n\treturn ns.doArithmetic(inputs, '*')","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/math/math.go#L152-L188","documentation":"After successfully casting both operands to int64, Hugo's `math.Mod` checks the divisor for zero before evaluating `ai % bi`, because integer modulo by zero would panic the Go runtime and crash the template render. Hugo converts that would-be panic into a normal template error.","triggerScenarios":"`{{ mod X 0 }}` or `{{ modBool X 0 }}` where the second argument evaluates to 0 — either a literal 0, a variable/param whose value is 0, or a string like \"0\" that cast converts to 0.","commonSituations":"Computing column/row grouping with a divisor from site config or front matter that is unset-then-defaulted to 0; paginator or grid math where `len $slice` is used as divisor and the slice is empty; loop counters where the divisor is derived from user data.","solutions":["Guard the divisor: `{{ if gt $n 0 }}{{ mod $i $n }}{{ end }}`.","If the divisor comes from config/params, give it a sane non-zero default: `{{ $cols := default 3 .Params.columns }}`.","When dividing by a collection length, check `{{ if $items }}` (non-empty) first."],"exampleFix":"<!-- before -->\n{{ mod $i (len $items) }}\n<!-- after -->\n{{ if $items }}{{ mod $i (len $items) }}{{ end }}","handlingStrategy":"validation","validationCode":"{{ if ne $b 0 }}{{ mod $a $b }}{{ else }}0{{ end }}","typeGuard":null,"tryCatchPattern":"result, err := ns.Mod(a, b)\nif err != nil {\n    // divisor was zero or non-integer; handle explicitly\n}","preventionTips":["Guard every `mod`/`div` with `{{ if ne $divisor 0 }}` when the divisor comes from data","Validate pagination/grid divisors (columns, page size) in site config at build start","Treat zero-length collections specially before using `len` as a modulo divisor"],"tags":["hugo","go-templates","math","divide-by-zero"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}