diff --git a/api/src/opentrons/protocol_engine/commands/move_labware.py b/api/src/opentrons/protocol_engine/commands/move_labware.py index d5c188d219f..7f52a8e83e4 100644 --- a/api/src/opentrons/protocol_engine/commands/move_labware.py +++ b/api/src/opentrons/protocol_engine/commands/move_labware.py @@ -186,6 +186,10 @@ async def execute(self, params: MoveLabwareParams) -> _ExecuteReturn: # noqa: C top_labware_definition=current_labware_definition, bottom_labware_id=available_new_location.labwareId, ) + if params.labwareId == available_new_location.labwareId: + raise LabwareMovementNotAllowedError( + "Cannot move a labware onto itself." + ) # Allow propagation of ModuleNotLoadedError. new_offset_id = self._equipment.find_applicable_labware_offset_id( diff --git a/api/tests/opentrons/protocol_engine/commands/test_move_labware.py b/api/tests/opentrons/protocol_engine/commands/test_move_labware.py index d1309761d8f..aa02d85349a 100644 --- a/api/tests/opentrons/protocol_engine/commands/test_move_labware.py +++ b/api/tests/opentrons/protocol_engine/commands/test_move_labware.py @@ -803,3 +803,38 @@ async def test_move_labware_raises_when_moving_fixed_trash_labware( match="Cannot move fixed trash labware 'My cool labware'.", ): await subject.execute(data) + + +async def test_labware_raises_when_moved_onto_itself( + decoy: Decoy, + subject: MoveLabwareImplementation, + state_view: StateView, +) -> None: + """It should raise when the OnLabwareLocation has the same labware ID as the labware being moved.""" + data = MoveLabwareParams( + labwareId="the-same-labware-id", + newLocation=OnLabwareLocation(labwareId="a-cool-labware-id"), + strategy=LabwareMovementStrategy.MANUAL_MOVE_WITH_PAUSE, + ) + + decoy.when(state_view.labware.get(labware_id="the-same-labware-id")).then_return( + LoadedLabware( + id="the-same-labware-id", + loadName="load-name", + definitionUri="opentrons-test/load-name/1", + location=DeckSlotLocation(slotName=DeckSlotName.SLOT_4), + offsetId=None, + ) + ) + + decoy.when( + state_view.geometry.ensure_location_not_occupied( + location=OnLabwareLocation(labwareId="a-cool-labware-id"), + ) + ).then_return(OnLabwareLocation(labwareId="the-same-labware-id")) + + with pytest.raises( + errors.LabwareMovementNotAllowedError, + match="Cannot move a labware onto itself.", + ): + await subject.execute(data)