{"record":{"id":"fed6f948e8314cce","repo":"gastownhall/beads","slug":"division-by-zero","errorCode":null,"errorMessage":"division by zero","messagePattern":"division by zero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/formula/range.go","lineNumber":283,"sourceCode":"\t}\n\n\tfor {\n\t\tswitch p.current().typ {\n\t\tcase tokMul:\n\t\t\tp.advance()\n\t\t\tright, err := p.parsePow()\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tleft *= right\n\t\tcase tokDiv:\n\t\t\tp.advance()\n\t\t\tright, err := p.parsePow()\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tif right == 0 {\n\t\t\t\treturn 0, fmt.Errorf(\"division by zero\")\n\t\t\t}\n\t\t\tleft /= right\n\t\tdefault:\n\t\t\treturn left, nil\n\t\t}\n\t}\n}\n\n// parsePow handles ^ (power, highest binary precedence, right-associative)\nfunc (p *exprParser) parsePow() (float64, error) {\n\tbase, err := p.parseUnary()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tif p.current().typ == tokPow {\n\t\tp.advance()\n\t\texp, err := p.parsePow() // Right-associative","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/formula/range.go#L265-L301","documentation":"parseMulDiv performs '/' only after checking the right operand is non-zero; a zero divisor raises this explicit error instead of returning IEEE +Inf. The library fails fast so users get a clear message rather than silently infinite/NaN results.","triggerScenarios":"EvaluateExpr with a division whose right side evaluates to 0, e.g. '10/0' or '8/(2-2)' in a range endpoint like 'range 1..10/0'.","commonSituations":"Variable placeholders substituted with 0 (empty config values), computed denominators that hit zero at runtime, off-by-one arithmetic like 'n-n'.","solutions":["Guard the divisor: use a non-zero constant or check the substituted variable value before evaluation","Rewrite as multiplication by a safe value or clamp the divisor (e.g. 'x/max(y,1)')","Log/inspect the variable values feeding the expression"],"exampleFix":"// before\nrange 1..count/0 { ... }\n// after\nrange 1..count/workers { ... } // ensure workers != 0","handlingStrategy":"validation","validationCode":"// before evaluating, ensure no variable that appears as a divisor is zero\nfor name, v := range vars {\n    if v == 0 { return fmt.Errorf(\"variable %s is zero; used as divisor\", name) }\n}","typeGuard":null,"tryCatchPattern":"val, err := EvaluateExpr(expr, vars)\nif err != nil && strings.Contains(err.Error(), \"division by zero\") {\n    // substitute safe defaults for zero variables and retry\n}","preventionTips":["Clamp divisor variables to a minimum of 1 before evaluation","Validate config values that feed divisions at load time","Prefer 'x/max(y,1)' patterns in user-authored expressions"],"tags":["formula","parser","arithmetic","division-by-zero"],"backgroundTag":"division-by-zero","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}