diff --git a/crates/native/src/feed_throttle.rs b/crates/native/src/feed_throttle.rs
--- a/crates/native/src/feed_throttle.rs
+++ b/crates/native/src/feed_throttle.rs
@@ -90,8 +90,10 @@ impl FeedThrottle {
     /// changes. A missing or malformed file just means no backoff is pending.
     pub fn load(file: &Path, now: i64) -> Self {
         let mut saved = std::fs::read(file).ok().and_then(|b| serde_json::from_slice::<Saved>(&b).ok()).unwrap_or_default();
-        // A wait far in the future means a broken file or a clock that jumped back: drop it.
-        if saved.not_before > now + MAX_THROTTLE_BACKOFF * 2 {
+        // A saved wait outside the sane range means a broken file, an edited value or a clock
+        // that jumped: drop it. A `not_before` near `i64::MIN` would otherwise wrap the
+        // subtraction in `wait` into a centuries-long wait (#774).
+        if !(0..=now.saturating_add(MAX_THROTTLE_BACKOFF * 2)).contains(&saved.not_before) {
             saved.not_before = 0;
         }
         Self { saved, file: Some(file.to_path_buf()), ..Self::new() }
@@ -112,7 +114,7 @@ impl FeedThrottle {
             let gap = WARM_GAPS.get(self.saved.failures as usize).or(WARM_GAPS.last()).copied().unwrap_or(WINDOW);
             at = at.max(last + gap);
         }
-        (at - now).max(0)
+        at.saturating_sub(now).max(0)
     }
 
     /// Notes that a request is being sent now.
@@ -375,4 +377,16 @@ mod tests {
         std::fs::write(&file, br#"{"unknown": true}"#).unwrap();
         assert_eq!(FeedThrottle::load(&file, NOW).wait(NOW), 0);
     }
+
+    #[test]
+    fn an_absurdly_old_saved_not_before_is_no_wait() {
+        let dir = tempfile::tempdir().unwrap();
+        let file = dir.path().join("feed-throttle.json");
+        // A hostile or corrupted `not_before` near i64::MIN once wrapped `at - now` into a
+        // wait of centuries (a debug-build panic, #774).
+        std::fs::write(&file, br#"{"not_before": -9223372036854775808, "throttles": 1}"#).unwrap();
+        assert_eq!(FeedThrottle::load(&file, NOW).wait(NOW), 0);
+        std::fs::write(&file, br#"{"not_before": -60, "throttles": 1}"#).unwrap();
+        assert_eq!(FeedThrottle::load(&file, NOW).wait(NOW), 0);
+    }
 }
diff --git a/crates/ui-egui/src/app.rs b/crates/ui-egui/src/app.rs
--- a/crates/ui-egui/src/app.rs
+++ b/crates/ui-egui/src/app.rs
@@ -173,6 +173,13 @@ const RESCAN_EVERY: i64 = 5 * 60;
 /// Coming back to the window re-checks, but not more often than this.
 const RESCAN_ON_FOCUS_AFTER: i64 = 30;
 
+/// A periodic update check is due `every` seconds after the last one. The saved time is
+/// hostile (an edited `app.ron`, a clock that ran fast and was later corrected): a time in
+/// the future or a corrupted `i64::MIN` never postpones the check (#774).
+fn update_check_due(last: Option<i64>, now: i64, every: i64) -> bool {
+    last.is_none_or(|t| t > now || now.saturating_sub(t) >= every)
+}
+
 impl LauncherUi {
     pub fn new(ctx: &egui::Context, backend: Box<dyn Backend>, settings: Settings) -> Self {
         let lang = effective_lang(&settings.language);
@@ -325,15 +332,15 @@ impl LauncherUi {
             self.last_detect = now;
         }
         let focused = ctx.input(|i| i.viewport().focused).unwrap_or(true);
-        let came_back = focused && !self.was_focused && now - self.last_detect >= RESCAN_ON_FOCUS_AFTER;
+        let came_back = focused && !self.was_focused && now.saturating_sub(self.last_detect) >= RESCAN_ON_FOCUS_AFTER;
         self.was_focused = focused;
-        if came_back || now - self.last_detect >= RESCAN_EVERY {
+        if came_back || now.saturating_sub(self.last_detect) >= RESCAN_EVERY {
             self.last_detect = now;
             self.backend.send(Command::Detect);
         }
         if let Some(every) = self.settings.check_every.seconds()
             && !self.checking
-            && self.settings.last_check.is_none_or(|t| now - t >= every)
+            && update_check_due(self.settings.last_check, now, every)
         {
             self.backend.send(Command::CheckForUpdates { force: false });
         }
@@ -813,3 +820,27 @@ impl LauncherUi {
         });
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::update_check_due;
+
+    const NOW: i64 = 1_791_500_000;
+    const EVERY: i64 = 24 * 60 * 60;
+
+    #[test]
+    fn a_check_is_due_after_its_interval() {
+        assert!(update_check_due(None, NOW, EVERY));
+        assert!(!update_check_due(Some(NOW - EVERY + 1), NOW, EVERY));
+        assert!(update_check_due(Some(NOW - EVERY), NOW, EVERY));
+    }
+
+    #[test]
+    fn a_saved_time_in_the_future_or_at_i64_min_never_postpones_a_check() {
+        // A clock that ran fast and was later corrected, or an edited `app.ron` (#774): the
+        // launcher would sit in the tray for weeks; `i64::MIN` panicked the subtraction.
+        assert!(update_check_due(Some(NOW + 60), NOW, EVERY));
+        assert!(update_check_due(Some(i64::MAX), NOW, EVERY));
+        assert!(update_check_due(Some(i64::MIN), NOW, EVERY));
+    }
+}
