ZhuLinsen/daily_stock_analysis · warning · HTTPException
invalid_params
invalid_params
Error message
analysis_date_from cannot be after analysis_date_to
What it means
Backtest endpoints call _validate_analysis_date_range (backtest.py:30-40) which returns HTTP 400 code=invalid_params when both analysis_date_from and analysis_date_to are supplied and from > to. It is a pure parameter-order sanity check executed before any service call, on /run, /results, /performance and /performance/{code}.
Source
Thrown at api/v1/endpoints/backtest.py:36
PerformanceMetrics,
)
from api.v1.schemas.common import ErrorResponse
from src.services.backtest_service import BacktestService
from src.storage import DatabaseManager
logger = logging.getLogger(__name__)
router = APIRouter()
BacktestAnalysisPhaseQuery = Literal["premarket", "intraday", "postmarket", "unknown"]
def _validate_analysis_date_range(
analysis_date_from: Optional[date],
analysis_date_to: Optional[date],
) -> None:
if analysis_date_from and analysis_date_to and analysis_date_from > analysis_date_to:
raise HTTPException(
status_code=400,
detail={
"error": "invalid_params",
"message": "analysis_date_from cannot be after analysis_date_to",
},
)
@router.post(
"/run",
response_model=BacktestRunResponse,
responses={
200: {"description": "回测执行完成"},
400: {"description": "请求参数错误", "model": ErrorResponse},
500: {"description": "服务器错误", "model": ErrorResponse},
},
summary="触发回测",
description="对历史分析记录进行回测评估,并写入 backtest_results/backtest_summaries",View on GitHub (pinned to 5159bd72e8)
Solutions
- Swap or recompute the range client-side so from <= to before sending
- Add client-side validation disabling submit when the range is inverted
- If an inverted range should mean 'empty window', decide explicitly: either normalize (min/max) or refuse early — do not rely on the server to guess
Example fix
# before
params = {"analysis_date_from": end.isoformat(), "analysis_date_to": start.isoformat()}
# after
params = {
"analysis_date_from": min(start, end).isoformat(),
"analysis_date_to": max(start, end).isoformat(),
} Defensive patterns
Strategy: validation
Validate before calling
def assert_valid_range(d_from: date, d_to: date) -> None:
if d_from and d_to and d_from > d_to:
raise ValueError("analysis_date_from must be <= analysis_date_to")
assert_valid_range(analysis_date_from, analysis_date_to)
# only now issue the backtest request Try / catch
try:
get_backtest(params)
except HTTPError as e:
if e.response.status_code == 400 and 'cannot be after' in e.response.text:
params['analysis_date_from'], params['analysis_date_to'] = sorted(
[params['analysis_date_from'], params['analysis_date_to']])
get_backtest(params)
else:
raise Prevention
- Bind date pickers so end >= start is enforced in the UI
- Run min/max normalization on any user-supplied range before building query params
- Unit-test client param builders with inverted ranges
When it happens
Trigger: Query params like ?analysis_date_from=2026-01-31&analysis_date_to=2026-01-01 on any backtest endpoint; date pickers whose end-date field is bound to the from parameter; timezone-less date strings parsed in unexpected order; form defaults where 'to' is yesterday and 'from' is today.
Common situations: Swapped date inputs in a custom UI; client sending ISO datetime strings where only dates are expected (FastAPI parses date, but value order can surprise); monthly-range widgets that emit first-day/end-day in the wrong fields.
Related errors
- analysis_date_from cannot be after analysis_date_to
- Invalid share image record ID
- Desktop share images require the configured backend origin
- Desktop share image source did not return HTML
- invalid_request
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/b19cd9aadc0a3f62.
Report an issue: GitHub.