Leantime/leantime · error · Leantime\Core\Exceptions\AuthorizationException

-32001

-32001

Error message

You do not have access to this project's tags.

What it means

Tags::getTags(projectId, term) gates on projectRepository->isUserAssignedToProject() for the CURRENT session user before merging ticket and canvas tags. That check admits admins/owners, org-wide ('all') and client-level projects, and direct assignments — everyone else gets AuthorizationException (JSON-RPC -32001). The gate exists because the JSON-RPC endpoint has no controller-level project context, so without it any caller could enumerate another project's tags by guessing ids.

Source

Thrown at app/Domain/Tags/Services/Tags.php:52

     * The JSON-RPC endpoint has no controller-level project gate (the retired
     * Api\Controllers\Tags forced session('currentProject'), but a JSON-RPC caller
     * can pass any projectId). isUserAssignedToProject() is the full access check —
     * it allows admins/owners, org-wide ("all") and client-level projects, and
     * directly assigned users — so this both preserves legitimate access and prevents
     * cross-project tag enumeration.
     *
     * @param  int  $projectId  The project to read tags from
     * @param  string  $term  Substring to filter tag suggestions by
     * @return array Matching tag strings (an empty array means no matches, NOT no access)
     *
     * @throws AuthorizationException If the user cannot access the project (distinct from a no-match empty result)
     *
     * @api
     */
    public function getTags(int $projectId, string $term): array
    {
        if (! $this->projectRepository->isUserAssignedToProject((int) session('userdata.id'), $projectId)) {
            throw new AuthorizationException('You do not have access to this project\'s tags.');
        }

        $tags = [];

        $ticketTags = $this->ticketRepository->getTags($projectId);
        $tags = $this->explodeAndMergeTags($ticketTags, $tags);

        $canvasTags = $this->canvasRepository->getTags($projectId);
        $tags = $this->explodeAndMergeTags($canvasTags, $tags);
        $unique = array_unique($tags);

        $tagArray = [];
        foreach ($unique as $tag) {
            if (str_contains($tag, strip_tags($term))) {
                $tagArray[] = $tag;
            }
        }

View on GitHub (pinned to 9a9f49f100)

Solutions

  1. Only query tags for a project the current user is assigned to (use the project from session('currentProject') when in doubt)
  2. Pre-check Projects::isUserAssignedToProject(userId, projectId) before requesting tag suggestions
  3. Catch AuthorizationException (-32001) and silently degrade the autocomplete rather than crashing the editor

Example fix

// before
$tags = $tagsService->getTags($projectId, $term);

// after
if (! $projectRepository->isUserAssignedToProject((int) session('userdata.id'), $projectId)) {
    return []; // no suggestions rather than an error
}
$tags = $tagsService->getTags($projectId, $term);
Defensive patterns

Strategy: validation

Validate before calling

$userId = (int) session('userdata.id');
if (! $projectRepository->isUserAssignedToProject($userId, $projectId)) {
    return []; // degrade autocomplete silently instead of erroring
}
$tags = $tagsService->getTags($projectId, $term);

Try / catch

try {
    $tags = $tagsService->getTags($projectId, $term);
} catch (\Leantime\Core\Exceptions\AuthorizationException $e) {
    // -32001: user not assigned to this project — return no suggestions
    $tags = [];
}

Prevention

When it happens

Trigger: Calling leantime.rpc.Tags.Tags.getTags with a projectId the session user is not assigned to; a tag autocomplete wired to a project the user can view metadata about but is not a member of; passing 0 or an invalid project id; a stale session after the user was removed from the project.

Common situations: Project switchers where some projects are visible but not joined; scripts probing ids over JSON-RPC; users working from an old tab after their assignment was revoked.

Related errors


AI-assisted analysis of Leantime/leantime@9a9f49f100 (2026-08-21). Data as JSON: /api/errors/79352e1ed9df1ad1. Report an issue: GitHub.