flarum/framework · error · MethodNotAllowedException

MethodNotAllowedException

Error message

MethodNotAllowedException

What it means

HTTP-method guard in the generic Api Endpoint::handle: the endpoint declares a route method (e.g. POST/DELETE), and the incoming JSON:API request used a different HTTP method for the same route, so the request cannot be dispatched to this endpoint and a 405-class MethodNotAllowedException is raised. Generic guard — the input at fault is the request's HTTP method.

Solutions

  1. Call the endpoint with the HTTP method it declares (check the endpoint class's $method, e.g. POST for CreateEndpoint, DELETE for DeleteEndpoint).
  2. Fix routing/client code that reuses one URL for multiple verbs incorrectly.
  3. Handle 405 at the client and advertise allowed methods.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at framework/core/src/Api/Endpoint/Endpoint.php:117 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/234dcac93e465594. Report an issue: GitHub.

Appendix: source

Thrown at framework/core/src/Api/Endpoint/Endpoint.php:117

    {
        if (! $this->action) {
            throw new RuntimeException('No action defined for endpoint ['.static::class.']');
        }

        return ($this->action)($context);
    }

    /**
     * @param Context $context
     */
    public function handle(\Tobyz\JsonApiServer\Context $context): ?Response
    {
        if (! isset($this->method, $this->path)) {
            throw new RuntimeException('No route defined for endpoint ['.static::class.']');
        }

        if (strtolower($context->method()) !== strtolower($this->method)) {
            throw new MethodNotAllowedException();
        }

        /** @var AbstractResource $collection */
        $collection = $context->collection;

        $context = $context->withModelId(
            $collection->id($context)
        );

        if ($context->modelId) {
            $context = $context->withModel(
                $this->findResource($context, $context->modelId)
            );
        }

        if (! $this->isVisible($context)) {
            throw new ForbiddenException();
        }

View on GitHub (pinned to 4b939f6853)