HKUDS/Vibe-Trading · error · ValueError

start {lower} is after end {upper}

Error message

start {lower} is after end {upper}

What it means

CashFlowSeries.between(start, end) normalizes both date bounds and requires start <= end; a reversed window is rejected instead of silently returning an empty slice, which would look like 'no flows in period' and mislead analysis.

Source

Thrown at agent/src/entities/cashflow.py:395

        """Select flows within an inclusive date window.

        Args:
            start: Earliest date to keep, inclusive. ``None`` leaves the window
                open on the left.
            end: Latest date to keep, inclusive. ``None`` leaves it open on the
                right.

        Returns:
            A new ``CashFlowSeries`` holding only flows inside the window.

        Raises:
            ValueError: If a bound is not a supported date value, or if
                ``start`` is later than ``end``.
        """
        lower = normalize_date(start, field_name="start") if start is not None else None
        upper = normalize_date(end, field_name="end") if end is not None else None
        if lower is not None and upper is not None and lower > upper:
            raise ValueError(f"start {lower} is after end {upper}")
        return self._rebuild(
            flow
            for flow in self.flows
            if (lower is None or flow.date >= lower)
            and (upper is None or flow.date <= upper)
        )

    def total(self, *, include_valuations: bool = False) -> float:
        """Sum the signed amounts.

        Valuation marks such as NAV are excluded by default: adding a mark to
        settled cash would overstate what was actually received.

        Args:
            include_valuations: Set True to include ``VALUATION_KINDS`` records,
                as required when computing a fund's IRR against terminal NAV.

        Returns:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Swap the arguments so start is the earlier bound
  2. If bounds come from user input, sort them: start, end = min(a,b), max(a,b) when order is irrelevant, or validate and surface a clear message

Example fix

# before
series.between(end='2024-12-31', start='2024-01-01')
# after
series.between(start='2024-01-01', end='2024-12-31')
Defensive patterns

Strategy: validation

Validate before calling

start, end = min(start, end), max(start, end)  # if order is user-supplied
series.between(start, end)

Try / catch

try:
    window = series.between(start, end)
except ValueError as e:
    if 'is after' in str(e):
        window = series.between(end, start)

Prevention

When it happens

Trigger: series.between('2024-12-31', '2024-01-01') or passing date bounds in the wrong order from swapped variables.

Common situations: Arguments transposed at the call site; a UI reporting period where the user picked the end date first; variables named from/to accidentally swapped.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/9d28aeaa560933f8. Report an issue: GitHub.