Leantime/leantime · error · Leantime\Core\Exceptions\AuthorizationException
-32001
-32001
Error message
You are not allowed to re-sort one or more of these projects.
What it means
Projects::patchProjectStatusAndSorting() is the authorized JSON-RPC entry point for the project kanban status+sort update. It parses params shaped as {status => jQuery-serialized string like "item[]=3&item[]=7"} (ids extracted by stripping the 7-char prefix), and for every project id requires userCanManageProject(): role of manager or higher AND assignment to that project (admins/owners bypass). Any failing id throws AuthorizationException, mapped to JSON-RPC -32001, before any write happens.
Source
Thrown at app/Domain/Projects/Services/Projects.php:2745
* @throws AuthorizationException If the caller cannot manage any project in the batch
*
* @api
*/
public function patchProjectStatusAndSorting(array $params, ?string $handler = null): bool
{
foreach ($params as $status => $projectList) {
if (! is_numeric($status) || empty($projectList)) {
continue;
}
foreach (explode('&', $projectList) as $projectString) {
// jQuery sortable serializes ids as "item[]=ID" (strip the 7-char prefix).
$projectId = (int) substr($projectString, 7);
if ($projectId <= 0) {
continue;
}
if (! $this->userCanManageProject($projectId)) {
throw new AuthorizationException('You are not allowed to re-sort one or more of these projects.');
}
}
}
return $this->updateProjectStatusAndSorting($params, $handler);
}
/**
* Authorized JSON-RPC entry point for Program Timeline (Gantt) re-sorting.
*
* Validates manager+ access for every entity in the mixed payload (pgm-/ticket-
* prefixed and legacy numeric ids) before delegating to updateProjectSorting().
* Ticket ids are resolved to their project so the same manage-access rule applies.
*
* @param array $params Map of (pgm-{id}|ticket-{id}|{id}) => sort position
* @return bool True on success (false only if the underlying write fails)
*
* @throws NotFoundException If a ticket-{id} key references a ticket that does not existView on GitHub (pinned to 9a9f49f100)
Solutions
- Ensure the acting user has manager+ role and is assigned to every project in the batch (admin/owner bypasses the assignment check)
- Hide drag-drop sorting UI for non-managers so the invalid call is never made
- Catch AuthorizationException (-32001), then verify assignments with Projects::isUserAssignedToProject and retry with only the projects the user can manage
Example fix
// before
$result = $projectsService->patchProjectStatusAndSorting($params);
// after
foreach ($params as $status => $list) {
foreach (explode('&', $list) as $item) {
$pid = (int) substr($item, 7);
if ($pid > 0 && ! $projectsService->userCanManageProject($pid)) {
unset($params[$status]); // or abort with a clear message
continue 2;
}
}
}
$result = $projectsService->patchProjectStatusAndSorting($params); Defensive patterns
Strategy: validation
Validate before calling
foreach ($params as $status => $list) {
foreach (explode('&', (string) $list) as $item) {
$pid = (int) substr($item, 7);
if ($pid > 0 && ! $projectsService->userCanManageProject($pid)) {
return ['error' => "No manage rights on project {$pid}"]; // fail before the call
}
}
} Try / catch
try {
$ok = $projectsService->patchProjectStatusAndSorting($params, $handler);
} catch (\Leantime\Core\Exceptions\AuthorizationException $e) {
// -32001: role or assignment missing — surface a permissions message, do not retry blindly
$notify->error($e->getMessage());
} Prevention
- Only enable drag-drop project sorting for manager+ users assigned to the visible projects
- Call the public Projects::userCanManageProject() pre-check for each id in the serialized payload
- Remember the payload format is jQuery-serialized 'item[]=ID' strings — parse with the same substr($s, 7) rule when validating
When it happens
Trigger: A user below manager dragging project cards between status columns; a manager re-sorting a project they are not assigned to; a payload that still contains project ids the caller lost access to after a role/assignment change.
Common situations: Drag-drop boards left open in a stale tab after the user's role was downgraded or assignment removed; organizations where managers manage only a subset of projects but the board lists all of them; scripts replaying a captured sort payload with a different account.
Related errors
AI-assisted analysis of Leantime/leantime@9a9f49f100 (2026-08-21).
Data as JSON: /api/errors/b7c1c16db9cbfe5c.
Report an issue: GitHub.