{"record":{"id":"c5238869b56208b3","repo":"vitessio/vitess","slug":"betainc-a-or-b-too-big-failed-to-converge","errorCode":null,"errorMessage":"betainc: a or b too big; failed to converge","messagePattern":"betainc: a or b too big; failed to converge","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/mathstats/beta.go","lineNumber":86,"sourceCode":"\n\t\t// Even step of the recurrence.\n\t\tnumer := mf * (b - mf) * x / ((a + 2*mf - 1) * (a + 2*mf))\n\t\td = 1 / raiseZero(1+numer*d)\n\t\tc = raiseZero(1 + numer/c)\n\t\th *= d * c\n\n\t\t// Odd step of the recurrence.\n\t\tnumer = -(a + mf) * (a + b + mf) * x / ((a + 2*mf) * (a + 2*mf + 1))\n\t\td = 1 / raiseZero(1+numer*d)\n\t\tc = raiseZero(1 + numer/c)\n\t\thfac := d * c\n\t\th *= hfac\n\n\t\tif math.Abs(hfac-1) < epsilon {\n\t\t\treturn h\n\t\t}\n\t}\n\tpanic(\"betainc: a or b too big; failed to converge\")\n}\n","sourceCodeStart":68,"sourceCodeEnd":88,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/mathstats/beta.go#L68-L88","documentation":"The incomplete beta function implementation (betacf continued-fraction loop) panics when the continued fraction fails to converge within the iteration limit. This happens for very large a or b parameters where the numeric algorithm cannot reach the epsilon tolerance.","triggerScenarios":"Calling the beta CDF / mathBetaInc path with extremely large shape parameters a or b, so the continued fraction in betacf never satisfies |hfac-1| < epsilon before exhausting iterations.","commonSituations":"Statistical computations with huge distribution parameters (e.g. computing tail probabilities of a Beta distribution with a or b in the thousands or millions); scaling issues after transforming data into p-value computations.","solutions":["Reduce the magnitude of a and b parameters, or rescale the problem before computing the incomplete beta.","Use a numerically stable alternative (e.g. regularized incomplete beta from a full stats library) for large parameters.","Cap or validate inputs in a wrapper so huge parameters are rejected with a proper error instead of a panic."],"exampleFix":"// before\nresult := mathstats.BetaInc(a, b, x) // a=1e6 panics\n// after\nif a > 1e4 || b > 1e4 {\n    return 0, fmt.Errorf(\"betainc: parameters too large: a=%v b=%v\", a, b)\n}\nresult := mathstats.BetaInc(a, b, x)","handlingStrategy":"try-catch","validationCode":"if a <= 0 || b <= 0 || a > 1e4 || b > 1e4 {\n    return fmt.Errorf(\"betainc: unsupported parameters a=%v b=%v\", a, b)\n}","typeGuard":null,"tryCatchPattern":"func safeBetaInc(a, b, x float64) (res float64, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"betainc failed: %v\", r)\n        }\n    }()\n    res = mathstats.BetaInc(a, b, x)\n    return res, nil\n}","preventionTips":["Bound shape parameters before calling into the stats code.","Wrap numerical library calls with a recover shim so panics become errors.","Prefer higher-level, well-conditioned formulas (e.g. compute the complement tail) for large parameters."],"tags":["numerical","math","panics"],"backgroundTag":"numerical-nonconvergence","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}