diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs
index ac808df89..3ead8d5ea 100644
--- a/Dalamud/Plugin/Internal/PluginManager.cs
+++ b/Dalamud/Plugin/Internal/PluginManager.cs
@@ -785,6 +785,20 @@ internal partial class PluginManager : IDisposable, IServiceType
{
Log.Debug($"Installing plugin {repoManifest.Name} (testing={useTesting})");
+ // If this plugin is in the default profile for whatever reason, delete the state
+ // If it was in multiple profiles and is still, the user uninstalled it and chose to keep it in there,
+ // or the user removed the plugin manually in which case we don't care
+ if (reason == PluginLoadReason.Installer)
+ {
+ // We don't need to apply, it doesn't matter
+ await this.profileManager.DefaultProfile.RemoveAsync(repoManifest.InternalName, false, false);
+ }
+ else
+ {
+ // If we are doing anything other than a fresh install, not having a workingPluginId is an error that must be fixed
+ Debug.Assert(inheritedWorkingPluginId != null, "inheritedWorkingPluginId != null");
+ }
+
// Ensure that we have a testing opt-in for this plugin if we are installing a testing version
if (useTesting && this.configuration.PluginTestingOptIns!.All(x => x.InternalName != repoManifest.InternalName))
{
diff --git a/Dalamud/Plugin/Internal/Profiles/Profile.cs b/Dalamud/Plugin/Internal/Profiles/Profile.cs
index ac46d9153..0b2d62ccf 100644
--- a/Dalamud/Plugin/Internal/Profiles/Profile.cs
+++ b/Dalamud/Plugin/Internal/Profiles/Profile.cs
@@ -200,17 +200,22 @@ internal class Profile
///
/// The internal name of the plugin.
/// Whether or not the current state should immediately be applied.
+ ///
+ /// Throw if certain operations are invalid.
+ /// * Throw if the plugin is not in this profile.
+ /// * If this is the default profile, check if we are in any other, then throw if we aren't.
+ ///
/// A representing the asynchronous operation.
- public async Task RemoveAsync(string internalName, bool apply = true)
+ public async Task RemoveAsync(string internalName, bool apply = true, bool guardrails = true)
{
ProfileModelV1.ProfileModelV1Plugin entry;
lock (this)
{
entry = this.modelV1.Plugins.FirstOrDefault(x => x.InternalName == internalName);
- if (entry == null)
+ if (entry == null && guardrails)
throw new ArgumentException($"No plugin \"{internalName}\" in profile \"{this.Guid}\"");
- if (!this.modelV1.Plugins.Remove(entry))
+ if (!this.modelV1.Plugins.Remove(entry) && guardrails)
throw new Exception("Couldn't remove plugin from model collection");
}
@@ -221,7 +226,7 @@ internal class Profile
{
await this.manager.DefaultProfile.AddOrUpdateAsync(internalName, this.IsEnabled && entry.IsEnabled, false);
}
- else
+ else if (guardrails)
{
throw new Exception("Removed plugin from default profile, but wasn't in any other profile");
}