Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

geninoliveira's avatar

Custom validation rule not working

Hi folks!

Something very strange is happening. I'm writing an API with the latest version of Laravel, and the custom validation aren't working! The code from the rule doesn't even touched!

Even this code is not working

Route::post('test', function (Request $request) {
    $validator = \Validator::make($request->all(), [
        'title' => [
            'required',
            function ($attribute, $value, $fail) {
                if ($value === 'foo') {
                    $fail('The '.$attribute.' is invalid.');
                }
            },
        ],
    ])->validate();
});

In this example, only 'required' rule is applied, and, yes, i'm sending the 'title' in request.

Anyone can help me?

0 likes
9 replies
thinkverse's avatar

What exactly isn't working? The closure rule is applied as it's supposed to if you write foo in the title and submit the error message is "The title is invalid." as defined in the closure.

And if submitted with a valid value, anything other than foo it's passed along to the post route.

Did you add a @error directive to your view to display the error message?

@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror
geninoliveira's avatar

@thinkverse Simply the custom rule is ignored, and the validation passes.

I'm testing with Postman, PHP 8.1.3 and Laravel 9.22.1.

The "normal" rules work normally.

thinkverse's avatar

@geninoliveira If it is for the /api routes you'll need to return the errors if the validation fails, read up on manually creating validators.

Route::post('test', function (Request $request) {
    $validator = Validator::make($request->all(), [
        'title' => [
            'required',
            function ($attribute, $value, $fail) {
                if ($value === 'foo') {
                    $fail('The '.$attribute.' is invalid.');
                }
            },
        ],
    ]);

    if ($validator->fails()) {
        $errors = $validator->errors();

        return response()
            ->json($errors->toArray());
    }

    $validated = $validator->validated();

    return response()
        ->json($validated);
});

thinkverse's avatar

@geninoliveira Don't see why it would interfere, it's simply adding a few more rules to the validator. I just tested and the closure still works for me.

Could you add a reproduction to GitHub?

thinkverse's avatar
Level 15

@geninoliveira In that case add an Accept header in your API call. If the form request sees it's an XHR request, the error message is returned as JSON.

If the request was an XHR request, an HTTP response with a 422 status code will be returned to the user including a JSON representation of the validation errors.

Accept: application/json

And that is verbatim from a section in Creating Form Requests just before the "Adding After Hooks To Form Requests" section.

geninoliveira's avatar

Thanks, folks. Seems like a reboot on my containers resolved the issue. I don't know why I didn't think of this before!.

Please or to participate in this conversation.