Incident ID: INC-20261010-500-SPIKE
Severity: Severity 1 (High Impact)
Trigger: Alert HighServerErrorRate fired on Prometheus (http://localhost:9091)
Affected Service: backend (http://localhost:8003/api/v1/reminders/summary)
Status: RESOLVED & VERIFIED
At 08:00:15 UTC, the Prometheus alerting engine fired a P1 alert indicating a spike in HTTP 500 errors exceeding the 1% error threshold over a 2-minute rolling window on the /api/v1/reminders/summary endpoint. The autonomous on-call poller (on-call-engineer/poll-alerts.py) ingested the alert payload, triggered the diagnostic workflow, localized the root cause via distributed tracing, reproduced the defect in an isolated test, applied a minimal safe patch, and verified that metric error rates returned to 0.
{
"alertname": "HighServerErrorRate",
"service": "personal-lifecycle-tracker-backend",
"environment": "production",
"endpoint": "/api/v1/reminders/summary",
"severity": "critical",
"value": "8.4%",
"dashboard": "http://localhost:3004/d/lifecycle-golden-signals"
}
rate(http_requests_total{status=~"5.."}[2m]) / rate(http_requests_total[2m])Querying Loki ({app="backend"} |= "ERROR"):
2026-10-10T08:00:14.238Z [ERROR] TraceID=4bf92f3577b34da6a3ce929d0e0e4736
Exception in calculate_upcoming_reminders: TypeError: '<=' not supported between instances of 'NoneType' and 'datetime.date'
File "app/routers/reminders.py", line 47, in get_reminders_summary
if item.due_date <= target_date:
4bf92f3577b34da6a3ce929d0e0e4736GET /api/v1/reminders/summary (HTTP 500, duration 42ms)
db.query: select_items_by_user (duration 6ms)python.eval: reminder_filtering (Exception recorded, duration 1ms)due_date is optional for warranties and long-running equipment). When users registered warranties with due_date = None, the reminders summary calculator executed direct relational comparisons (item.due_date <= target_date) without validating that item.due_date is not None./api/v1/reminders/summary to fail with unhandled TypeError.backend/tests/test_reminders.py:
def test_reminders_summary_with_null_due_date(client, auth_headers):
# Item with due_date = None
client.post("/api/v1/items", json={"name": "TV Warranty", "type": "warranty", "due_date": None}, headers=auth_headers)
response = client.get("/api/v1/reminders/summary", headers=auth_headers)
assert response.status_code == 200
assert response.json()["total_undated"] >= 1
backend/app/routers/reminders.py to defensively guard against None due dates:
# Defensively filter items with valid due dates
if item.due_date and item.due_date <= target_date:
upcoming_items.append(item)
elif item.due_date is None:
undated_items.append(item)
make test-backend inside Docker. All 27 unit and integration tests passed.curl -f http://localhost:8003/api/v1/reminders/summary returns HTTP 200 OK.http_requests_total{status="500"} flattened; 5-minute error rate returned to 0.0%.HighServerErrorRate as resolved.on-call-engineer/audit-trail.log.