unclecode/crawl4ai · error · HTTPException
Invalid status: {status}. Must be one of: all, active, compl
Error message
Invalid status: {status}. Must be one of: all, active, completed, success, error What it means
GET /monitor/requests validates its status query parameter against the fixed set {all, active, completed, success, error} before touching the monitor; anything else raises HTTPException(400) listing the valid values. This is an input-validation guard at the API boundary, not an internal failure.
Source
Thrown at deploy/docker/monitor_routes.py:36
try:
monitor = get_monitor()
return await monitor.get_health_summary()
except Exception as e:
logger.error(f"Error getting health: {e}")
raise HTTPException(500, str(e))
@router.get("/requests")
async def get_requests(status: str = "all", limit: int = 50):
"""Get active and completed requests.
Args:
status: Filter by 'active', 'completed', 'success', 'error', or 'all'
limit: Max number of completed requests to return (default 50)
"""
# Input validation
if status not in ["all", "active", "completed", "success", "error"]:
raise HTTPException(400, f"Invalid status: {status}. Must be one of: all, active, completed, success, error")
if limit < 1 or limit > 1000:
raise HTTPException(400, f"Invalid limit: {limit}. Must be between 1 and 1000")
try:
monitor = get_monitor()
if status == "active":
return {"active": monitor.get_active_requests(), "completed": []}
elif status == "completed":
return {"active": [], "completed": monitor.get_completed_requests(limit)}
elif status in ["success", "error"]:
return {"active": [], "completed": monitor.get_completed_requests(limit, status)}
else: # "all"
return {
"active": monitor.get_active_requests(),
"completed": monitor.get_completed_requests(limit)
}
except Exception as e:View on GitHub (pinned to 7e80152142)
Solutions
- Use one of: all, active, completed, success, error — exact lowercase match.
- Lowercase and trim the filter client-side before sending.
- Treat the 400 body as authoritative; it enumerates the allowed set.
Example fix
# before GET /monitor/requests?status=Running # after GET /monitor/requests?status=active
Defensive patterns
Strategy: validation
Validate before calling
VALID_STATUSES = {"all", "active", "completed", "success", "error"}
def safe_status(s: str) -> str:
s = (s or "all").strip().lower()
return s if s in VALID_STATUSES else "all" Type guard
def is_valid_monitor_status(s) -> bool:
return isinstance(s, str) and s in {"all", "active", "completed", "success", "error"} Prevention
- Normalize status filters to lowercase and trim whitespace before sending.
- Drive UI dropdowns from the documented five-value set.
- Treat any 400 from this route as a client bug — fix the caller, don't retry.
When it happens
Trigger: GET /monitor/requests?status=running, ?status=FAILED (wrong case), ?status=error%20 (whitespace), or any other unlisted string.
Common situations: Clients assuming dashboard vocabulary ('running', 'pending') matches the API's; case-sensitive queries; URL-encoding mistakes adding whitespace.
Related errors
- str(e)
- Invalid limit: {limit}. Must be between 1 and 1000
- Container not found: ${config.container_selector}
- str(e)
- error_msg
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/a570611198e874bc.
Report an issue: GitHub.