ZhuLinsen/daily_stock_analysis · error · ValueError
analysis_date_from cannot be after analysis_date_to
Error message
analysis_date_from cannot be after analysis_date_to
What it means
Plain ValueError raised at the top of the backtest batch run method when both analysis_date_from and analysis_date_to are supplied and from > to. It is a request-argument sanity check that fires before any normalization or data access, so an invalid window fails fast.
Source
Thrown at src/services/backtest_service.py:59
self.db = db_manager or DatabaseManager.get_instance()
self.repo = BacktestRepository(self.db)
self.stock_repo = StockRepository(self.db)
def run_backtest(
self,
*,
code: Optional[str] = None,
force: bool = False,
eval_window_days: Optional[int] = None,
min_age_days: Optional[int] = None,
analysis_date_from: Optional[date] = None,
analysis_date_to: Optional[date] = None,
limit: int = 200,
) -> Dict[str, Any]:
config = get_config()
if analysis_date_from and analysis_date_to and analysis_date_from > analysis_date_to:
raise ValueError("analysis_date_from cannot be after analysis_date_to")
query_code = self._normalize_code(code)
diagnostic_code = self._normalize_code_for_display(code)
if eval_window_days is None:
eval_window_days = getattr(config, "backtest_eval_window_days", 10)
if (
isinstance(eval_window_days, bool)
or not isinstance(eval_window_days, int)
or eval_window_days <= 0
):
raise ValueError("eval_window_days must be a positive integer")
if min_age_days is None:
min_age_days = getattr(config, "backtest_min_age_days", 14)
engine_version = getattr(config, "backtest_engine_version", "v1")
neutral_band_pct = float(getattr(config, "backtest_neutral_band_pct", 2.0))
View on GitHub (pinned to 5159bd72e8)
Solutions
- Swap or correct the arguments so analysis_date_from <= analysis_date_to (both ISO YYYY-MM-DD).
- Validate/normalize the range client-side before calling the API.
- If the range is optional, send only one bound or neither instead of an inverted pair.
Example fix
# before run_backtests(analysis_date_from=date(2026, 6, 1), analysis_date_to=date(2026, 5, 1)) # after run_backtests(analysis_date_from=date(2026, 5, 1), analysis_date_to=date(2026, 6, 1))
Defensive patterns
Strategy: validation
Validate before calling
if analysis_date_from and analysis_date_to and analysis_date_from > analysis_date_to:
analysis_date_from, analysis_date_to = analysis_date_to, analysis_date_from # or reject with 400 Type guard
function isValidDateRange(from?: string, to?: string): boolean {
if (!from || !to) return true;
return new Date(from) <= new Date(to);
} Try / catch
try:
result = backtest_service.run_backtests(
analysis_date_from=from_date, analysis_date_to=to_date
)
except ValueError as exc:
return JSONResponse(status_code=400, content={"detail": str(exc)}) Prevention
- Enforce from <= to in date-range pickers before enabling submit.
- Send dates as ISO YYYY-MM-DD and construct them with explicit timezone handling.
- Treat this ValueError as a 400 at the API boundary since it signals a bad request, not a server fault.
When it happens
Trigger: Calling the backtest service/API with analysis_date_from='2026-06-01' and analysis_date_to='2026-05-01' — swapped date pickers, wrong ISO order, or timezone/day-boundary mistakes.
Common situations: UI date-range pickers returning end-before-start; client sending dates in DD/MM/YYYY parsed as YYYY-MM-DD; DST or server-timezone shifts making an 'same day' range invert; hardcoded test dates left in config.
Related errors
- invalid_params
- Invalid share image record ID
- Desktop share images require the configured backend origin
- Desktop share image source did not return HTML
- eval_window_days must be positive
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/42fc5d5f4a70894d.
Report an issue: GitHub.