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
- Only query tags for a project the current user is assigned to (use the project from session('currentProject') when in doubt)
- Pre-check Projects::isUserAssignedToProject(userId, projectId) before requesting tag suggestions
- 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
- Drive tag autocomplete from the user's actually-assigned projects (e.g. session('currentProject'))
- Pre-check isUserAssignedToProject before switching the autocomplete target
- Distinguish -32001 (no access) from an empty result (no matches) in your error handling
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.