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

-32002

-32002

Error message

The task you tried to edit could not be found.

What it means

Tickets::patchTicket() fetches the ticket with getTicket(), which returns false BOTH when the id matches no row AND when the current user cannot access the ticket's project — so this NotFoundException (JSON-RPC -32002) deliberately doubles as the no-access answer, avoiding existence leaks. For tickets that do resolve, authorize(TicketsPermissions::EDIT, projectId) then enforces editor+ in the ticket's own project before the patch runs.

Source

Thrown at app/Domain/Tickets/Services/Tickets.php:2712

     * editor or above AND be assigned to the ticket's project (prevents
     * cross-project IDOR via a smuggled ticket id).
     *
     * @param  int  $id  The ticket id to update
     * @param  array  $values  The fields to update
     * @return bool True on success (false only if the underlying write fails)
     *
     * @throws AuthorizationException If the caller is not an editor, or is not assigned to the ticket's project
     * @throws NotFoundException If the ticket does not exist
     *
     * @api
     */
    #[RequiresPermission(TicketsPermissions::EDIT, entityScoped: true)]
    public function patchTicket(int $id, array $values): bool
    {
        // getTicket() returns false when the user can't access the ticket's project.
        $ticket = $this->getTicket($id);
        if (! $ticket) {
            throw new NotFoundException('The task you tried to edit could not be found.');
        }

        // Editor+ in the ticket's project (project-scoped role, not the session role) AND
        // access to it. Replaces the prior session-scoped userIsAtLeast + assignment checks.
        $this->authorize(TicketsPermissions::EDIT, (int) $ticket->projectId);

        return $this->patch($id, $values);
    }

    /**
     * Set a ticket's status from a semantic status type ("new" / "inprogress" / "done").
     *
     * Used by the program cross-project kanban: columns are status types, but the value
     * written is always a real status key that exists in the ticket's OWN project, so a
     * drag on the program board can never leave the task with a status its project board
     * doesn't recognize. Authorization (edit in the ticket's project) is delegated to
     * patchTicket().
     *

View on GitHub (pinned to 9a9f49f100)

Solutions

  1. Confirm the id resolves for THIS caller first: Tickets::getTicket($id) must return a row (it applies the same access scoping)
  2. Refresh the board and re-apply the edit with current ids
  3. Catch NotFoundException (-32002) and treat it as 'not found or not yours' — prompt a reload rather than a retry

Example fix

// before
$ticketsService->patchTicket($id, $values);

// after
if (! $ticketsService->getTicket($id)) {
    return ['error' => 'Task missing or not accessible — reload the board'];
}
$ticketsService->patchTicket($id, $values);
Defensive patterns

Strategy: validation

Validate before calling

$ticket = $ticketsService->getTicket($id); // false = missing OR out of scope
if (! $ticket) {
    return ['error' => 'Task not found or not accessible — reload'];
}
$ok = $ticketsService->patchTicket($id, $values);

Try / catch

try {
    $ok = $ticketsService->patchTicket($id, $values);
} catch (\Leantime\Core\Exceptions\NotFoundException $e) {
    // -32002 covers BOTH deleted and no-access by design — reload the board
    $board->reloadTicket($id);
}

Prevention

When it happens

Trigger: Patching a deleted or wrong-pasted ticket id; dragging/editing a card from a stale board after the ticket was deleted mid-session; a ticket whose project the caller has no access to (indistinguishable from missing by design).

Common situations: Stale kanban/Gantt tabs during concurrent edits; scripts iterating ticket ids across projects the account cannot see; users removed from a project but still holding an open board.

Related errors


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