flarum/framework · error · MethodNotAllowedException

MethodNotAllowedException ($method)

Error message

MethodNotAllowedException ($method)

What it means

Thrown in ResolveRoute::process when FastRoute returns METHOD_NOT_ALLOWED: the URI matches a registered route but the HTTP verb (e.g. DELETE on a GET/POST-only route) is not in that route's allowed methods list. Surfaces as 405; the message names the offending method. Flarum routes typically allow only GET and POST, so other verbs indicate a client using verbs the route does not declare.

Solutions

  1. Use the HTTP method the route was registered with (usually GET or POST in Flarum)
  2. Check the route definition in Extend\Routes to see which verbs it accepts
  3. Fix client code or library configuration that issues the wrong verb
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at framework/core/src/Http/Middleware/ResolveRoute.php:52 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15). Data as JSON: /api/errors/c85ea92e7ea33484. Report an issue: GitHub.

Appendix: source

Thrown at framework/core/src/Http/Middleware/ResolveRoute.php:52

     * @throws RouteNotFoundException
     */
    public function process(Request $request, Handler $handler): Response
    {
        $method = $request->getMethod();
        $uri = $request->getUri()->getPath() ?: '/';

        // Strip trailing slash so that e.g. /d/123-slug/ resolves the same as /d/123-slug.
        if ($uri !== '/' && str_ends_with($uri, '/')) {
            $uri = rtrim($uri, '/');
        }

        $routeInfo = $this->getDispatcher()->dispatch($method, $uri);

        switch ($routeInfo[0]) {
            case Dispatcher::NOT_FOUND:
                throw new RouteNotFoundException($uri);
            case Dispatcher::METHOD_NOT_ALLOWED:
                throw new MethodNotAllowedException($method);
            default:
                $request = $request
                    ->withAttribute('routeName', $routeInfo[1]['name'])
                    ->withAttribute('routeHandler', $routeInfo[1]['handler'])
                    ->withAttribute('routeParameters', $routeInfo[2]);

                return $handler->handle($request);
        }
    }

    protected function getDispatcher(): Dispatcher\GroupCountBased
    {
        if (! isset($this->dispatcher)) {
            $this->dispatcher = new Dispatcher\GroupCountBased($this->routes->getRouteData());
        }

        return $this->dispatcher;
    }

View on GitHub (pinned to 4b939f6853)