...And my problem was I was using a var as a loop boundary and assuming it would be treated as an int.

optimize only produces floats. So I had

var num_clusters = (optimize(10., 3., 25., -20));

Then, later, I used
int i
for (i = 0; i < num_clusters; i++) {
read_one_element_of_something_with_exactly_num_cluster_elements();
}

I expected num_clusters to be rounded down to nearest int. I don't know why I expected that. So when num_clusters=1.1, the for loop is executed 2x, leading to one more read than is possible. So, it crashed.

I guess, better to use
int num_clusters = (int)(optimize(10., 3., 25., -20));
when really needing an int.