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

  1. Confirm the rule still exists via GET /alerts/rules before deleting, or simply handle 404 as 'already gone' in idempotent delete flows
  2. Refresh the rule list in the UI and retry the delete against a current id
  3. If the id should exist, verify the API server points at the same database file/DSN the rules were created in
  4. 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

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.