Here is a general trace of what would happen in your case. Each * should be considered one extra level of recursion:
int[] list = {42, 17, 33, 55};
mergeSort(array0 = list)
left0 = {42,17}
right0 = {33,55}
*mergeSort(array1 = left0)
*left1 = {42}
*right1 = {17}
**mergeSort(array2 = left1) -- Exit immediately
**mergeSort(array3 = right1) -- Exit immediately
**merge(result = array1, left = left1, right = right1) -- result.length = 2
*mergeSort(array4 = right0)
*left2 = {33}
*right2 = {55}
**mergeSort(array5 = left2) -- Exit immediately
**mergeSort(array6 = right2) -- Exit immediately
**merge(result = array4, left = left2, right = right2) -- result.length = 2
merge(result = array0, left = left0, right = right0) -- result.length = 4
I think you are confused with what array is being sent as the result parameter to the merge method when recursively checking each half of the array. The result parameter is the array before it was split into left and right, not after, so the length of the result array parameter can never be less than 2.