Error 381, “Invalid property-array index”, fires when code indexes into a property array with a value the array does not currently have. Property arrays are the indexed properties controls expose, ListBox.List(i), ComboBox.Text arrays in classic VB, control arrays themselves, and their valid indices run from 0 to one less than the count. An index copied from a count, a stale index kept after items were removed, or a -1 from “nothing selected” used as an address all raise error 381. The array is fine; the index is out of bounds.
With lstResults
If .ListIndex >= 0 Then
chosen = .List(.ListIndex) ' safe: a selection exists
End If
End With
' .List(.ListIndex) with ListIndex = -1 raises error 381.
Count elements; looping 0 To Count overshoots by one on the last pass. Keep For i = 0 To .ListCount - 1 as a reflex..Selected(i)), each needing the same bounds discipline. Treating a loop over Selected as if it were over List, with a mismatched count, lands on error 381 just the same.
If indices are provably in range, the property array may belong to a control whose contents changed between the check and the use: another event or a bound data refresh can shrink the list in between. Snapshot the values you need in one pass rather than indexing repeatedly across statements that can trigger events.
What is a property array? A property that behaves like an array because it takes an index, such as a list control's List property where List(0) is the first entry. Its size changes as items are added and removed, so its valid index range changes too.
Why is -1 such a common cause? Because -1 is the standard “no selection” value returned by list controls, and it flows silently into index positions in code that does not check for it. As an index it is invalid, producing error 381.