I believe the issue here is that the size of the array is unknown, hence you don't get any validation errors for the rest of the images.
You might be good if you send the total number of images that needs to be validated in a hidden field or something, and then iterate in your request validator and add a rule for each index.
This is what worked for me:
<form action="/testing-upload" method="post" enctype="multipart/form-data">
@csrf
<input class="fileUpload @error('image.0') is-invalid @enderror" name="image[]" type="file" value="{{ old('image.0') }}">
<input class="fileUpload @error('image.1') is-invalid @enderror" name="image[]" type="file" value="{{ old('image.1') }}">
<input class="fileUpload @error('image.2') is-invalid @enderror" name="image[]" type="file" value="{{ old('image.2') }}">
<input class="fileUpload @error('image.3') is-invalid @enderror" name="image[]" type="file" value="{{ old('image.3') }}">
<input type="hidden" name="images" value="4">
<button type="submit">Submit</button>
</form>
NOTE the hidden field with total number of images expected, you can also get that dynamically if you need to.
Then in the controller:
$images = $request->input('images');
$rules = [];
for ($i = 0; $i < $images; $i++) {
$rules['image.' . $i] = 'required|image|mimes:jpeg,png,jpg|max:10000';
}
$validate = Validator::make($request->all(), $rules);
dd($validate->fails(), $validate->errors());
You can do the same in the form request as well, instead of $request->input it will be $this->input()
And this is the result that I got from selecting only the first image:
Illuminate\Support\MessageBag {#1249 ▼
#messages: array:3 [▼
"image.1" => array:1 [▼
0 => "The image.1 field is required."
]
"image.2" => array:1 [▼
0 => "The image.2 field is required."
]
"image.3" => array:1 [▼
0 => "The image.3 field is required."
]
]
#format: ":message"
}
3 other error messages which is expected.