{"record":{"id":"b8c157312a1a0d3a","repo":"vitessio/vitess","slug":"sample-is-too-small","errorCode":null,"errorMessage":"sample is too small","messagePattern":"sample is too small","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/mathstats/ttest.go","lineNumber":79,"sourceCode":"\t\tp = 2 * (1 - dist.CDF(math.Abs(t)))\n\tcase LocationLess:\n\t\tp = dist.CDF(t)\n\tcase LocationGreater:\n\t\tp = 1 - dist.CDF(t)\n\t}\n\treturn &TTestResult{N1: n1, N2: n2, T: t, DoF: dof, AltHypothesis: alt, P: p}\n}\n\n// A TTestSample is a sample that can be used for a one or two sample\n// t-test.\ntype TTestSample interface {\n\tWeight() float64\n\tMean() float64\n\tVariance() float64\n}\n\nvar (\n\tErrSampleSize        = errors.New(\"sample is too small\")\n\tErrZeroVariance      = errors.New(\"sample has zero variance\")\n\tErrMismatchedSamples = errors.New(\"samples have different lengths\")\n)\n\n// TwoSampleTTest performs a two-sample (unpaired) Student's t-test on\n// samples x1 and x2. This is a test of the null hypothesis that x1\n// and x2 are drawn from populations with equal means. It assumes x1\n// and x2 are independent samples, that the distributions have equal\n// variance, and that the populations are normally distributed.\nfunc TwoSampleTTest(x1, x2 TTestSample, alt LocationHypothesis) (*TTestResult, error) {\n\tn1, n2 := x1.Weight(), x2.Weight()\n\tif n1 == 0 || n2 == 0 {\n\t\treturn nil, ErrSampleSize\n\t}\n\tv1, v2 := x1.Variance(), x2.Variance()\n\tif v1 == 0 && v2 == 0 {\n\t\treturn nil, ErrZeroVariance\n\t}","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/mathstats/ttest.go#L61-L97","documentation":"ErrSampleSize is a sentinel error in the mathstats t-test package: it means a t-test was called with an empty or single-element sample, so there are not enough observations to compute a meaningful t-statistic and degrees of freedom. The t-test functions (TwoSampleTTest, TwoSampleWelchTTest, PairedTTest, OneSampleTTest) return it as a sentinel so callers can compare with errors.Is.","triggerScenarios":"TwoSampleTTest when x1.Weight()==0 or x2.Weight()==0; TwoSampleWelchTTest or PairedTTest when a sample has weight/length <= 1; OneSampleTTest when the sample's Weight()==0.","commonSituations":"Passing an empty slice after filtering data; feeding a stream that produced zero rows; calling a t-test on a single observation; forgetting that Weight() (not len()) drives the check for TTestSample implementations.","solutions":["Check sample sizes (weight or length) before calling the t-test and handle the small-sample case explicitly","Collect at least 2 observations per sample (Welch/paired) before running the test","errors.Is(err, mathstats.ErrSampleSize) to branch to a degenerate-stats path instead of failing"],"exampleFix":"// before\nres, err := mathstats.TwoSampleWelchTTest(s1, s2, mathstats.LocationDiffers) // panics logic if empty\n// after\nif s1.Weight() <= 1 || s2.Weight() <= 1 {\n    return nil, errors.New(\"need at least 2 observations per sample\")\n}\nres, err := mathstats.TwoSampleWelchTTest(s1, s2, mathstats.LocationDiffers)","handlingStrategy":"validation","validationCode":"if len(data) == 0 { return errors.New(\"need observations before t-test\") } // and for Welch/paired: if len(data) < 2 { ... }\nif w1 == 0 || w2 == 0 { return errors.New(\"empty sample\") }","typeGuard":"func usableSample(s mathstats.TTestSample, minWeight float64) bool { return s.Weight() >= minWeight }","tryCatchPattern":"res, err := mathstats.OneSampleTTest(x, mu0, alt)\nif errors.Is(err, mathstats.ErrSampleSize) { return nil, ErrNotEnoughData }\nif err != nil { return nil, err }","preventionTips":["Check Weight()/len() before every t-test call","Require >= 2 observations for Welch and paired tests","Return a typed 'insufficient data' result early in your pipeline"],"tags":["statistics","ttest","input-validation"],"backgroundTag":"sample-size-too-small","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}