phalcon/cphalcon · error · Phalcon\Mvc\Micro\Exceptions\NotFoundHandlerNotCallable

Not-Found handler is not callable or is not defined

Error message

Not-Found handler is not callable or is not defined

What it means

Thrown near the end of Micro::handle when no route matched and the configured not-found handler ($this->notFoundHandler, set via Micro::notFound) is either unset or not a callable. After the 'micro:beforeNotFound' event fires and no handler can be invoked, this sentinel error is raised so the application fails loudly instead of silently producing an empty response; the input at fault is the value registered as the 404 handler.

Solutions

  1. Register a callable with $app->notFound(function () {...})
  2. Ensure the handler variable assigned to notFound() is a Closure or invokable
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at phalcon/Mvc/Micro.zep:609 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/db29d2999921ade6. Report an issue: GitHub.

Appendix: source

Thrown at phalcon/Mvc/Micro.zep:609

                    }
                }
            } else {
                 /**
                  * Calling beforeNotFound event
                  */
                if this->eventsManager !== null {
                    if this->eventsManager->fire("micro:beforeNotFound", this) === false {
                        return false;
                    }
                }

                /**
                 * Check if a notfoundhandler is defined and it's callable
                 */
                let notFoundHandler = this->notFoundHandler;

                if unlikely !is_callable(notFoundHandler) {
                    throw new NotFoundHandlerNotCallable();
                }

                /**
                 * Call the Not-Found handler
                 */
                let returnedValue = call_user_func(notFoundHandler);
            }

            /**
             * Calling afterHandleRoute event
             */
            if this->eventsManager !== null {
                this->eventsManager->fire("micro:afterHandleRoute", this, returnedValue);
            }

            let finishHandlers = this->finishHandlers;
            let this->stopped = false;

View on GitHub (pinned to b7419de9cd)