I had similar problems and it seems that update_sub_field function is bit buggy at the moment. However, I managed to update existing repeater subfield with following code, it seems exactly like yours but it’s wrapped in have_rows() loop:
// field_54d5f40bbbe1d = repeater
// field_54e4513b63547 = subfield
if( have_rows('field_54d5f40bbbe1d', $post_id) ):
$row_index = 0;
while ( have_rows('field_54d5f40bbbe1d', $post_id) ) : the_row();
$row_index++;
// just some generic conditional logic to update specific sub_field, in this case by 'name' sub_field
if(get_sub_field('name') == $what_i_want_it_to_be){
update_sub_field( array("field_54d5f40bbbe1d", $row_index, "field_54e4513b63547"), 'test', $post_id);
}
endwhile;
endif;
I think looping this through have_rows() shouldn’t have anything to do with updating sub field. Hope this helps.