ZhuLinsen/daily_stock_analysis · warning · AlertNotFoundError
not_found
not_found
Error message
Alert rule not found: {rule_id} What it means
DELETE /alerts/rules/{rule_id} returns HTTP 404 code=not_found when AlertService.delete_rule(rule_id) reports the rule as not deleted — i.e. no row with that integer id exists (alerts.py:145-153). The endpoint wraps AlertNotFoundError via _not_found; any other exception becomes a 500 with 'Delete alert rule failed'.
Source
Thrown at api/v1/endpoints/alerts.py:153
except UnsupportedAlertTypeError as exc:
raise _bad_request(exc, error=exc.error_code)
except AlertServiceError as exc:
raise _bad_request(exc, error=exc.error_code)
except Exception as exc:
raise _internal_error("Update alert rule failed", exc)
@router.delete(
"/rules/{rule_id}",
response_model=AlertDeleteResponse,
responses={404: {"model": ErrorResponse}, 500: {"model": ErrorResponse}},
summary="Delete alert rule",
)
def delete_rule(rule_id: int) -> AlertDeleteResponse:
service = AlertService()
try:
if not service.delete_rule(rule_id):
raise AlertNotFoundError(f"Alert rule not found: {rule_id}")
return AlertDeleteResponse(deleted=1)
except AlertNotFoundError as exc:
raise _not_found(exc)
except Exception as exc:
raise _internal_error("Delete alert rule failed", exc)
@router.post(
"/rules/{rule_id}/enable",
response_model=AlertRuleItem,
responses={404: {"model": ErrorResponse}, 500: {"model": ErrorResponse}},
summary="Enable alert rule",
)
def enable_rule(rule_id: int) -> AlertRuleItem:
service = AlertService()
try:
return AlertRuleItem(**service.enable_rule(rule_id, True))
except AlertNotFoundError as exc:View on GitHub (pinned to 5159bd72e8)
Solutions
- Confirm the rule still exists via GET /alerts/rules before deleting, or simply handle 404 as 'already gone' in idempotent delete flows
- Refresh the rule list in the UI and retry the delete against a current id
- If the id should exist, verify the API server points at the same database file/DSN the rules were created in
- Check server logs for the 500 branch ('Delete alert rule failed') in case the not-found result is actually masking a service-level failure
Example fix
# before
resp = requests.delete(f"{base}/alerts/rules/{rule_id}")
resp.raise_for_status()
# after
resp = requests.delete(f"{base}/alerts/rules/{rule_id}")
if resp.status_code == 404:
logger.info("rule %s already deleted", rule_id) # idempotent success
else:
resp.raise_for_status() Defensive patterns
Strategy: try-catch
Validate before calling
# Python client: pre-check existence for non-idempotent flows
import requests
if requests.get(f"{BASE}/api/v1/alerts/rules/{rule_id}").status_code == 200:
resp = requests.delete(f"{BASE}/api/v1/alerts/rules/{rule_id}")
else:
log(f"rule {rule_id} already gone") Try / catch
try:
delete_rule(rule_id)
except HTTPError as e:
if e.response.status_code == 404:
return # already deleted — idempotent success
raise Prevention
- Refresh the rule list before rendering delete actions
- Treat delete as idempotent in automation scripts (404 == done)
- Ensure all admin clients point at the same alerts DB
When it happens
Trigger: Deleting a rule that was already removed (double delete, two admin sessions); passing an id from a stale list page; passing a non-existent or malformed id (non-integer ids fail earlier at path parsing with FastAPI's 422); rule id drift after a database reset/migration.
Common situations: Web UI list not refreshed after another client deleted the rule; SQLite file swapped or reset between listing and deleting; automation scripts hard-coding rule ids across environments; concurrent delete requests racing so the second one 404s.
Related errors
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/08fab12d2b582c7a.
Report an issue: GitHub.