diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp
index 4d4bce6ced17d..4d66f24b8c7bb 100644
--- a/src/activity_item_handling.cpp
+++ b/src/activity_item_handling.cpp
@@ -536,14 +536,21 @@ static std::list<item> obtain_activity_items( player_activity &act, player &p )
         res.insert( res.begin(), excess.begin(), excess.end() );
     }
     // Load anything that remains (if any) into the activity
-    act.targets.clear();
-    act.values.clear();
-    if( !items.empty() ) {
+    if( items.size() > act.targets.size() ) {
         for( const drop_location &drop : convert_to_locations( items ) ) {
             act.targets.push_back( drop.first );
             act.values.push_back( drop.second );
         }
     }
+    // remove items already dropped from the targets list by checking if pointers were invalidated
+    for( int i = act.targets.size() - 1; i >= 0; i-- ) {
+        const auto target_iter = act.targets.cbegin() + i;
+        const auto value_iter = act.values.cbegin() + i;
+        if( !*target_iter ) {
+            act.targets.erase( target_iter );
+            act.values.erase( value_iter );
+        }
+    }
     // And cancel if its empty. If its not, we modified in place and we will continue
     // to resolve the drop next turn. This is different from the pickup logic which
     // creates a brand new activity every turn and cancels the old activity