flarum/framework · error · PermissionDeniedException

PermissionDeniedException

Error message

PermissionDeniedException

What it means

Thrown in AccessTokenResource::delete when the token being deleted is the access token of the current session. Deleting it would terminate the caller's own active login, which must only happen through logout, so the deletion is refused with PermissionDeniedException (403).

Solutions

  1. Use the logout endpoint instead of DELETE on the token resource to end the current session
  2. Delete a different (non-current) token, e.g. one listed for the user's other devices/sessions
  3. If programmatic termination of the current session is required, invalidate the session directly rather than via the API
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at framework/core/src/Api/Resource/AccessTokenResource.php:133 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/c2d76b9952a4c534. Report an issue: GitHub.

Appendix: source

Thrown at framework/core/src/Api/Resource/AccessTokenResource.php:133

    {
        $this->events->dispatch(new DeveloperTokenCreated($model));

        return parent::created($model, $context);
    }

    /**
     * @param AccessToken $model
     * @param \Flarum\Api\Context $context
     * @throws PermissionDeniedException
     */
    public function delete(object $model, \Tobyz\JsonApiServer\Context $context): void
    {
        /** @var Session|null $session */
        $session = $context->request->getAttribute('session');

        // Current session should only be terminated through logout.
        if ($session && $model->token === $session->get('access_token')) {
            throw new PermissionDeniedException();
        }

        // Don't give away the existence of the token.
        if ($context->getActor()->cannot('revoke', $model)) {
            throw new ModelNotFoundException();
        }

        $model->delete();
    }
}

View on GitHub (pinned to 4b939f6853)