vitessio/vitess · error

sample is too small

Error message

sample is too small

What it means

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.

Source

Thrown at go/mathstats/ttest.go:79

		p = 2 * (1 - dist.CDF(math.Abs(t)))
	case LocationLess:
		p = dist.CDF(t)
	case LocationGreater:
		p = 1 - dist.CDF(t)
	}
	return &TTestResult{N1: n1, N2: n2, T: t, DoF: dof, AltHypothesis: alt, P: p}
}

// A TTestSample is a sample that can be used for a one or two sample
// t-test.
type TTestSample interface {
	Weight() float64
	Mean() float64
	Variance() float64
}

var (
	ErrSampleSize        = errors.New("sample is too small")
	ErrZeroVariance      = errors.New("sample has zero variance")
	ErrMismatchedSamples = errors.New("samples have different lengths")
)

// TwoSampleTTest performs a two-sample (unpaired) Student's t-test on
// samples x1 and x2. This is a test of the null hypothesis that x1
// and x2 are drawn from populations with equal means. It assumes x1
// and x2 are independent samples, that the distributions have equal
// variance, and that the populations are normally distributed.
func TwoSampleTTest(x1, x2 TTestSample, alt LocationHypothesis) (*TTestResult, error) {
	n1, n2 := x1.Weight(), x2.Weight()
	if n1 == 0 || n2 == 0 {
		return nil, ErrSampleSize
	}
	v1, v2 := x1.Variance(), x2.Variance()
	if v1 == 0 && v2 == 0 {
		return nil, ErrZeroVariance
	}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check sample sizes (weight or length) before calling the t-test and handle the small-sample case explicitly
  2. Collect at least 2 observations per sample (Welch/paired) before running the test
  3. errors.Is(err, mathstats.ErrSampleSize) to branch to a degenerate-stats path instead of failing

Example fix

// before
res, err := mathstats.TwoSampleWelchTTest(s1, s2, mathstats.LocationDiffers) // panics logic if empty
// after
if s1.Weight() <= 1 || s2.Weight() <= 1 {
    return nil, errors.New("need at least 2 observations per sample")
}
res, err := mathstats.TwoSampleWelchTTest(s1, s2, mathstats.LocationDiffers)
Defensive patterns

Strategy: validation

Validate before calling

if len(data) == 0 { return errors.New("need observations before t-test") } // and for Welch/paired: if len(data) < 2 { ... }
if w1 == 0 || w2 == 0 { return errors.New("empty sample") }

Type guard

func usableSample(s mathstats.TTestSample, minWeight float64) bool { return s.Weight() >= minWeight }

Try / catch

res, err := mathstats.OneSampleTTest(x, mu0, alt)
if errors.Is(err, mathstats.ErrSampleSize) { return nil, ErrNotEnoughData }
if err != nil { return nil, err }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/b8c157312a1a0d3a. Report an issue: GitHub.