diff --git a/kloppy/domain/models/event.py b/kloppy/domain/models/event.py
index 4f81bad87..c31b305ae 100644
--- a/kloppy/domain/models/event.py
+++ b/kloppy/domain/models/event.py
@@ -1085,10 +1085,14 @@ def _update_formations_and_positions(self):
replacement_player_position = event.player.positions.last(
default=PositionType.Unknown
)
- event.replacement_player.set_position(
- event.time,
- replacement_player_position,
- )
+ if (
+ event.replacement_player.positions.last(default=None)
+ is None
+ ):
+ event.replacement_player.set_position(
+ event.time,
+ replacement_player_position,
+ )
event.player.set_position(event.time, None)
elif isinstance(event, FormationChangeEvent):
diff --git a/kloppy/infra/serializers/event/statsperform/deserializer.py b/kloppy/infra/serializers/event/statsperform/deserializer.py
index e7f0dc3f0..9dfac2350 100644
--- a/kloppy/infra/serializers/event/statsperform/deserializer.py
+++ b/kloppy/infra/serializers/event/statsperform/deserializer.py
@@ -387,6 +387,9 @@ def _parse_formation_change(raw_event: OptaEvent, team: Team) -> Dict:
player_positions = {}
for player_id, position_id in zip(player_ids, position_ids):
player = team.get_player_by_id(player_id)
+ if player is None:
+ continue
+
position = positions_mapping[int(position_id)]
player_positions[player] = position
diff --git a/kloppy/tests/files/opta_f24.xml b/kloppy/tests/files/opta_f24.xml
index 47c46c0b4..53270b19b 100644
--- a/kloppy/tests/files/opta_f24.xml
+++ b/kloppy/tests/files/opta_f24.xml
@@ -114,6 +114,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -332,6 +347,14 @@
+
+
+
+
+
+
+
+
diff --git a/kloppy/tests/test_adapter.py b/kloppy/tests/test_adapter.py
index 6b9dd997c..571eb0af5 100644
--- a/kloppy/tests/test_adapter.py
+++ b/kloppy/tests/test_adapter.py
@@ -67,4 +67,4 @@ def list_directory(
# Asserts borrowed from `test_opta.py`
assert dataset.metadata.provider == Provider.OPTA
assert dataset.dataset_type == DatasetType.EVENT
- assert len(dataset.events) == 39
+ assert len(dataset.events) == 41