From b75c7b177acbf4ec3839f82c32f592a302dd416e Mon Sep 17 00:00:00 2001 From: JonKazama-Hellion Date: Fri, 8 May 2026 21:00:19 +0200 Subject: [PATCH] Move RunRetentionSweepIfDue to Phase 2 (depends on MessageManager.Store) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Smoke test in Task 6 surfaced a NullReferenceException at Plugin.cs:885 — the retention sweep was scheduled in Phase 1 but dereferences MessageManager.Store, which is only allocated in Phase 2 (LoadAsync). Move the call after MessageManager init. Drop the comment that wrongly claimed independence from Phase-2 services. --- HellionChat/Plugin.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/HellionChat/Plugin.cs b/HellionChat/Plugin.cs index d6b3728..47c8fae 100755 --- a/HellionChat/Plugin.cs +++ b/HellionChat/Plugin.cs @@ -471,12 +471,6 @@ public sealed class Plugin : IAsyncDalamudPlugin Interface.UiBuilder.DisableCutsceneUiHide = true; Interface.UiBuilder.DisableGposeUiHide = true; - // Hellion Chat — daily retention sweep, off-thread so it never - // blocks plugin load. Skips itself when disabled or already ran - // within the past 24 hours. Pure fire-and-forget on a background - // thread, so it doesn't depend on Phase-2 services being live. - RunRetentionSweepIfDue(); - if (Config.ShowEmotes) _ = EmoteCache.LoadData(); // Fire-and-forget intentional, exceptions are caught inside } @@ -518,6 +512,11 @@ public sealed class Plugin : IAsyncDalamudPlugin MessageManager = new MessageManager(this); + // Daily retention sweep, fire-and-forget. Lives in Phase 2 because + // it dereferences MessageManager.Store. Skips itself when disabled + // or when it already ran within the past 24 hours. + RunRetentionSweepIfDue(); + // Hellion Chat — Auto-Tell-Tabs service. Subscribes to the // MessageManager's MessageProcessed event for live tells and // to ClientState.Logout for the cleanup pass. Created after