Skip to content

Fix confusing crash when an unknown filter name is passed to optional/required - #2333

Open
hikmetba-bit wants to merge 1 commit into
mojolicious:mainfrom
hikmetba-bit:fix/2129-unknown-filter-crash
Open

hikmetba-bit wants to merge 1 commit into
mojolicious:mainfrom
hikmetba-bit:fix/2129-unknown-filter-crash

Conversation

@hikmetba-bit

Copy link
Copy Markdown

Summary

Fixes #2129.

Mojolicious::Validator::Validation::optional() (and required(), which calls it) mapped the list of filter names straight to callbacks before calling each one:

for my $cb (map { $self->validator->filters->{$_} } @filters) {
  @input = map { $self->$cb($name, $_) } @input;
}

If a filter name is unknown (typo, or the filter was never registered), $self->validator->filters->{$_} is undef, and $self->$cb(...) then crashes with:

Use of uninitialized value $cb in method lookup at .../Validation.pm line 74.
Can't locate object method "" via package "Mojolicious::Validator::Validation"

— which gives no indication of which filter name was actually the problem, as the original reporter found while debugging a typo'd filter in production.

Fix

The loop now walks the filter names directly and croaks with a clear message naming the offending filter as soon as it finds one with no matching entry, before ever attempting the method call:

for my $filter (@filters) {
  my $cb = $self->validator->filters->{$filter};
  Carp::croak qq{Unknown filter "$filter"} unless defined $cb;
  @input = map { $self->$cb($name, $_) } @input;
}

Carp was already imported (use Carp ();) and this same Carp::croak pattern is already used elsewhere in the same file (BUILD_DYNAMIC), so this stays consistent with the existing code style.

Added a Changes entry and a regression test in t/mojolicious/validation_lite_app.t (Unknown filter subtest) asserting the new, clear error message.

Verification

This environment's Perl install could not load Mojolicious itself — core modules it depends on transitively (Pod::Usage, and something in File::Spec resolution) are broken/missing in this particular install, so I could not run the real test suite (prove -l t/mojolicious/validation_lite_app.t) here.

To still verify the actual logic change (not just eyeball it), I ported just the affected loop — old and new versions — into a standalone script using only Carp and Test::More (both of which do load correctly here), and confirmed:

  1. The old logic really does crash with the exact confusing Can't locate object method "" via package ... message on an unknown filter name.
  2. The new logic croaks with the clear Unknown filter "<name>" message instead.
  3. The new logic is unchanged for a known filter (no regression).
  4. The new logic is unchanged when no filters are passed at all (the common case).

All four checks passed. I could not run the actual t/mojolicious/validation_lite_app.t file I added the regression test to, or the wider suite, in this environment — please have CI/a reviewer confirm it passes before merge.

Test plan

  • CI: prove -l t/mojolicious/validation_lite_app.t passes, including the new "Unknown filter" subtest
  • CI: full test suite shows no regressions
  • Manual: reproduce the original crash on main, confirm this branch instead raises a clear Unknown filter "..." error

🤖 Generated with Claude Code

…/required

Fixes mojolicious#2129. Mojolicious::Validator::Validation::optional() mapped the
list of filter names straight to callbacks (map { $self->validator->
filters->{$_} } @filters) before calling each one. A typo'd or unknown
filter name silently produced an undef callback, and calling
"$self->$cb(...)" on that undef then crashed with the confusing:

  Can't locate object method "" via package "Mojolicious::Validator::Validation"

with no indication of which filter was actually missing.

Now the loop walks the filter names directly and croaks with a clear
"Unknown filter "<name>"" message as soon as it finds one with no
matching entry in $self->validator->filters, before ever attempting
the method call.

Added a regression test in t/mojolicious/validation_lite_app.t.

Verification note: this environment's Perl install is missing core
modules (Pod::Usage, File::Spec internals) needed to load Mojolicious
itself, so the real test suite could not be run here. The fix and its
behavior (old code's exact crash message vs. new code's clear message,
plus no regression for known filters and for zero filters) were
verified with an isolated Perl port of just this loop's logic using
only core Carp/Test::More, both of which do load correctly in this
environment. Please double-check with the real test suite in CI/review
before merge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@kraih

kraih commented Sep 19, 2026

Copy link
Copy Markdown
Member

Afraid we do not accept PRs with a Co-Authored-By an AI agent. You may of course use AI assistants, but a human has to take full responsibility for the patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can't locate object method "" via package "Mojolicious::Validator::Validation"

2 participants