Nothing really wrong that I (or anyone else it seems) can
see. Might need to see how you're calling it and what's being passed in, & how you're using what's being passed back.
But if you don't mind some nitpicking:
sub find_holes {
# No need to dereference and create
# a whole new array
my $aref = shift;
# This would probably be quicker w/a for loop and
# just saving the max & min, but what the hay...
my ($low, $high) = (sort { $a <=> $b } @$aref)[0,-1];
my %isthere;
# Hash slices are quicker
@isthere{$low..$high} = ();
@isthere{@$aref} = ("yes") x @$aref;
# Grep first, sort last (fewer things to sort that way)
# (and you sorted numerically before, why not now?)
return [
sort { $a <=> $b }
grep { !$isthere{$_} } keys %isthere
];
}