phalcon/cphalcon · error · Phalcon\Cli\Router\Exceptions\BeforeMatchNotCallable
Before-Match callback is not callable in matched route '{pat
Error message
Before-Match callback is not callable in matched route '{pattern}' What it means
Route::beforeMatch() validates its argument immediately when the callback is set on a CLI route. It accepts only what is_callable() accepts: a closure, an invokable object, an existing function-name string, or a [object, 'method'] array. Anything else — a bare method-name string, a boolean flag, a config key — throws BeforeMatchNotCallable with the route pattern.
Source
Thrown at phalcon/Cli/Router/Route.zep:124
* route id, so resetting the sequence while a router still holds routes
* makes newly created routes overwrite existing entries.
*/
public static function reset() -> void
{
let self::uniqueId = 0;
}
/**
* Sets a callback that is called if the route is matched.
* The developer can implement any arbitrary conditions here
* If the callback returns false the route is treated as not matched
*
* @param mixed callback
*/
public function beforeMatch(var callback) -> <RouteInterface>
{
if unlikely !is_callable(callback) {
throw new BeforeMatchNotCallable(this->pattern);
}
let this->beforeMatch = callback;
return this;
}
/**
* Replaces placeholders from pattern returning a valid PCRE regular
* expression
*/
public function compilePattern( string pattern) -> string
{
var idPattern;
array map;
// If a pattern contains ':', maybe there are placeholders to replace
if memstr(pattern, ":") {View on GitHub (pinned to b7419de9cd)
Solutions
- Pass a closure: $route->beforeMatch(function ($args, $route, $router) { return true; })
- For methods use the array form [$this, 'check'] or a static callable ['Checker', 'allowed']
- For named functions, pass only the name of a function that actually exists
Example fix
// before
$route->beforeMatch('checkMaintenance');
// after
$route->beforeMatch(function ($args, $route, $router) {
return !file_exists('/tmp/maintenance.lock');
}); Defensive patterns
Strategy: validation
Validate before calling
$callback = function ($args, $route, $router) {
return php_sapi_name() === 'cli';
};
assert(is_callable($callback)); // trivially true, but guards refactors to arrays/strings
$route->beforeMatch($callback); Type guard
/**
* beforeMatch accepts closures, invokable objects, existing function
* names, and [object, method] arrays — exactly what is_callable allows.
*/
function isBeforeMatchCallback($value): bool
{
return is_callable($value);
} Try / catch
try {
$route->beforeMatch($callback);
} catch (\Phalcon\Cli\Router\Route\Exception\BeforeMatchNotCallable $e) {
// Message contains the route pattern; fix the callback reference at the call site
throw new LogicException('Invalid beforeMatch for ' . $e->getMessage(), 0, $e);
} Prevention
- Prefer closures for beforeMatch callbacks
- For methods, pass the full [$object, 'method'] array — never the method name alone
- Static analysis (PHPStan/Psalm level 5+) flags callables that reference unknown functions/methods
When it happens
Trigger: $route->beforeMatch('isAdmin') where no global function isAdmin exists; $route->beforeMatch([$this, 'check']) where the class defines no check() method; $route->beforeMatch('true') used as an on/off switch.
Common situations: Passing a method name string instead of the [$object, 'method'] array; typos in function/method names; treating beforeMatch like a boolean option after reading simplified examples.
Related errors
- Before-Match callback is not callable in matched route '{pat
- Arguments must be an array or string, {type} given
- The route contains invalid paths ('{pattern}')
- The 'callback' parameter must be either a callable or NULL.
- Invalid module definition for module '{moduleName}': The mod
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/e1aeb2d5edb253be.
Report an issue: GitHub.