From 8efb6cbbaa1975aace73c5e2daf588516e2012c5 Mon Sep 17 00:00:00 2001 From: glenneth Date: Sun, 18 Jan 2026 19:51:43 +0300 Subject: [PATCH] Fix rate limiter corruption: cleanup negative amounts on startup The r-simple-rate library has a bug where rate limit counters can go negative and never reset. This happens because the reset condition only triggers when amount >= 0, so negative amounts are permanently stuck. This fix adds: - cleanup-corrupted-rate-limits function to delete corrupted entries - db:connected trigger to run cleanup automatically on startup This prevents the 429 error loops that occurred when counters became corrupted with large negative values. --- limiter.lisp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/limiter.lisp b/limiter.lisp index 84f79e1..305f0c8 100644 --- a/limiter.lisp +++ b/limiter.lisp @@ -2,6 +2,23 @@ (in-package :asteroid) +(defun cleanup-corrupted-rate-limits () + "Clean up corrupted rate limit entries with negative amounts. + The r-simple-rate library has a bug where the reset condition only triggers + when amount >= 0, so negative amounts never reset. This function deletes + any corrupted entries so they can be recreated fresh." + (handler-case + (let ((deleted (db:remove 'simple-rate::tracking + (db:query (:< 'amount 0))))) + (when (and deleted (> deleted 0)) + (l:info :rate-limiter "Cleaned up ~a corrupted rate limit entries" deleted))) + (error (e) + (l:warn :rate-limiter "Failed to cleanup rate limits: ~a" e)))) + +(define-trigger db:connected () + "Clean up any corrupted rate limit entries on startup" + (cleanup-corrupted-rate-limits)) + (defun render-rate-limit-error-page() (clip:process-to-string (load-template "error")