diff --git a/server/src/events/invite.rs b/server/src/events/invite.rs
index 4cb05d4a10..40d42c16ed 100644
--- a/server/src/events/invite.rs
+++ b/server/src/events/invite.rs
@@ -8,7 +8,7 @@ use common::{
         invite::{Invite, InviteKind, InviteResponse, PendingInvites},
         ChatType,
     },
-    trade::Trades,
+    trade::{TradeResult, Trades},
     uid::Uid,
 };
 use common_net::{
@@ -60,6 +60,8 @@ pub fn handle_invite(
     }
 
     let mut pending_invites = state.ecs().write_storage::<PendingInvites>();
+    let mut agents = state.ecs().write_storage::<comp::Agent>();
+    let mut invites = state.ecs().write_storage::<Invite>();
 
     if let InviteKind::Group = kind {
         if !group_manip::can_invite(
@@ -72,11 +74,29 @@ pub fn handle_invite(
         ) {
             return;
         }
+    } else {
+        // cancel current trades for inviter before inviting someone else to trade
+        let mut trades = state.ecs().write_resource::<Trades>();
+        if let Some(inviter_uid) = uids.get(inviter).copied() {
+            if let Some(active_trade) = trades.entity_trades.get(&inviter_uid).copied() {
+                trades
+                    .decline_trade(active_trade, inviter_uid)
+                    .and_then(|u| state.ecs().entity_from_uid(u.0))
+                    .map(|e| {
+                        if let Some(client) = clients.get(e) {
+                            client
+                                .send_fallible(ServerGeneral::FinishedTrade(TradeResult::Declined));
+                        }
+                        if let Some(agent) = agents.get_mut(e) {
+                            agent
+                                .inbox
+                                .push_back(AgentEvent::FinishedTrade(TradeResult::Declined));
+                        }
+                    });
+            }
+        };
     }
 
-    let mut agents = state.ecs().write_storage::<comp::Agent>();
-    let mut invites = state.ecs().write_storage::<Invite>();
-
     if invites.contains(invitee) {
         // Inform inviter that there is already an invite
         if let Some(client) = clients.get(inviter) {
diff --git a/server/src/events/player.rs b/server/src/events/player.rs
index 0bd57edab1..83112b3568 100644
--- a/server/src/events/player.rs
+++ b/server/src/events/player.rs
@@ -1,7 +1,8 @@
 use super::Event;
 use crate::{
-    client::Client, metrics::PlayerMetrics, persistence::character_updater::CharacterUpdater,
-    presence::Presence, state_ext::StateExt, BattleModeBuffer, Server,
+    client::Client, events::trade::cancel_trade_for, metrics::PlayerMetrics,
+    persistence::character_updater::CharacterUpdater, presence::Presence, state_ext::StateExt,
+    BattleModeBuffer, Server,
 };
 use common::{
     comp,
@@ -114,13 +115,14 @@ pub fn handle_client_disconnect(
     skip_persistence: bool,
 ) -> Event {
     span!(_guard, "handle_client_disconnect");
+    cancel_trade_for(server, entity);
     if let Some(client) = server
         .state()
         .ecs()
         .write_storage::<Client>()
         .get_mut(entity)
     {
-        // NOTE: There are not and likely willl not be a way to safeguard against
+        // NOTE: There are not and likely will not be a way to safeguard against
         // receiving multiple `ServerEvent::ClientDisconnect` messages in a tick
         // intended for the same player, so the `None` case here is *not* a bug
         // and we should not log it as a potential issue.