HKUDS/Vibe-Trading · error · ValueError
label_end_times has {span_ends.size} entries but the sample
Error message
label_end_times has {span_ends.size} entries but the sample has {n_samples} What it means
Raised by _as_label_spans when the label_end_times array has a different length than the sample it is meant to describe. The purging logic indexes label spans row-by-row, so a length mismatch would silently purge the wrong observations or crash later. The library fails fast with an explicit size comparison.
Source
Thrown at agent/src/quantlib/crossvalidation.py:157
positions = np.searchsorted(starts, ends, side="right") - 1
positions = np.clip(positions, np.arange(len(starts)), len(starts) - 1)
span_ends = positions.astype(int)
else:
span_ends = np.asarray(label_end_times, dtype=float)
if span_ends.ndim != 1:
raise ValueError(f"label_end_times must be 1-D, got shape {span_ends.shape}")
if span_ends.size == 0:
raise ValueError("label_end_times is empty")
if not np.isfinite(span_ends).all():
raise ValueError("label_end_times holds a non-finite value")
span_ends = span_ends.astype(int)
if (span_ends < np.arange(span_ends.size)).any():
raise ValueError(
"a label cannot end before the observation it belongs to starts"
)
if n_samples is not None and span_ends.size != n_samples:
raise ValueError(
f"label_end_times has {span_ends.size} entries but the sample has {n_samples}"
)
return span_ends
def _apply_purge_and_embargo(
label_ends: np.ndarray,
test_mask: np.ndarray,
embargo_size: int,
) -> tuple[np.ndarray, int, int]:
"""Build a training mask that is purged of overlap and embargoed after.
Args:
label_ends: Last positional index each observation's label covers.
test_mask: Boolean mask of the test observations.
embargo_size: Observations embargoed immediately after each test block.
Returns:View on GitHub (pinned to 80ffdda44c)
Solutions
- Align lengths: recompute or reindex label_end_times on exactly the rows of the sample (e.g. df.loc[X.index]
- Check for accidental slicing of X (train-only frames) while passing full-length labels
- Add an assert len(label_end_times) == len(X) before calling the splitter
Example fix
// before splits = list(purged_kfold_splits(X.dropna(), n_folds=5, label_end_times=labels_full)) // after X2 = X.dropna() labels = labels_full[X2.index] splits = list(purged_kfold_splits(X2, n_folds=5, label_end_times=labels))
Defensive patterns
Strategy: validation
Validate before calling
assert len(label_end_times) == len(X), f'{len(label_end_times)} labels vs {len(X)} rows' Prevention
- Keep labels attached to the frame (a column) instead of a separate array
- After dropna/filter operations, subset labels with X.index
When it happens
Trigger: Calling purged_kfold_splits/purged_walk_forward_splits/combinatorial_purged_splits/detect_boundary_leakage with label_end_times of length m while X (or n_samples) has n != m rows, e.g. labels computed on the full dataset but features filtered to a subset.
Common situations: Dropping NaN rows from features after computing labels, train/test pre-filtering, concatenating frames out of order, or passing labels from a different ticker/period than the sample.
Related errors
- a label cannot end before the observation it belongs to star
- n_folds must be at least {MIN_FOLDS}, got {n_folds}
- {n_samples} samples cannot make {n_folds} folds
- embargo_fraction must be in [0, 1), got {embargo_fraction}
- Purge and embargo removed all training samples for fold {fol
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/b2916494e2edd295.
Report an issue: GitHub.