Prerequisites
Rclone Pre-flight Checklist (if applicable)
Bug Description
Cancelling a running backup changes the task status to cancelled, but the restic process continues running and uploading data. In my test, the process remained active until I terminated it manually.
The likely cause is the module-local execution registry in app/server/modules/tasks/tasks.lifecycle.ts:
const taskExecutions = new Map<string, TaskExecution>();
Nitro can load the task runner and cancellation route from separate server bundles. The cancellation route then sees no matching execution and follows this branch:
if (!execution) {
taskStore.cancel(taskId, TASK_CANCELLED_ERROR);
return true;
}
This marks the task cancelled without calling execution.cancel(). The running process continues, while the UI and database report that it stopped.
The execution registry should be shared across server bundles, similar to the process-wide task listener state added in #1146. For example:
type ProcessWithTaskExecutions = NodeJS.Process & {
__zerobyteTaskExecutions?: Map<string, TaskExecution>;
};
const runtimeProcess = process as ProcessWithTaskExecutions;
const taskExecutions = (runtimeProcess.__zerobyteTaskExecutions ??= new Map());
safeSpawn should also resolve only after the child emits close. Resolving immediately from its error handler can release task and repository state before the OS process has exited.
Steps to Reproduce
- Start a backup large enough to remain active for several minutes.
- Confirm that
restic and its backend process are running with docker top.
- Cancel the backup from the Zerobyte UI.
- Observe that the task immediately changes to
cancelled.
- Run
docker top again.
- Observe that
restic and its backend process are still running and continue transferring data.
Expected Behavior
The task should enter cancelling, signal the registered execution, and remain in that state until the child process closes. It should change to cancelled only after restic has exited.
Zerobyte version / commit
v0.42.0 - b87c59b
Deployment Method
Docker Compose
Backup/Repository Context
- Repository type: rclone
- Storage backend: Proton Drive
- Backup operation: Folders containing image files
- Restic version: 0.19.1
- Rclone version during reproduction: 1.75.1
The cancellation failure occurs in Zerobyte before the backend process is signaled, so it is not specific to Proton Drive or rclone.
Logs / Error Messages
Zerobyte marked the task cancelled, then continued receiving progress from the running backup:
Failed to persist backup task progress for <task-id>:
Task <task-id> was not updated with progress; current status is cancelled
The database row showed:
status: cancelled
cancellation_requested: 1
error: Task was cancelled by the user
outcome: cancelled
The processes were still running afterward:
/usr/local/bin/restic --repo rclone:Proton:Backup/Immich backup ...
rclone serve restic --stdio ... Proton:Backup/Immich
Both processes stopped only after manual termination.
Prerequisites
Rclone Pre-flight Checklist (if applicable)
rclone listremotesandrclone lsd remote:on the host and they workBug Description
Cancelling a running backup changes the task status to
cancelled, but theresticprocess continues running and uploading data. In my test, the process remained active until I terminated it manually.The likely cause is the module-local execution registry in
app/server/modules/tasks/tasks.lifecycle.ts:Nitro can load the task runner and cancellation route from separate server bundles. The cancellation route then sees no matching execution and follows this branch:
This marks the task
cancelledwithout callingexecution.cancel(). The running process continues, while the UI and database report that it stopped.The execution registry should be shared across server bundles, similar to the process-wide task listener state added in #1146. For example:
safeSpawnshould also resolve only after the child emits close. Resolving immediately from its error handler can release task and repository state before the OS process has exited.Steps to Reproduce
resticand its backend process are running withdocker top.cancelled.docker topagain.resticand its backend process are still running and continue transferring data.Expected Behavior
The task should enter
cancelling, signal the registered execution, and remain in that state until the child process closes. It should change tocancelledonly afterrestichas exited.Zerobyte version / commit
v0.42.0 - b87c59b
Deployment Method
Docker Compose
Backup/Repository Context
The cancellation failure occurs in Zerobyte before the backend process is signaled, so it is not specific to Proton Drive or rclone.
Logs / Error Messages
Zerobyte marked the task cancelled, then continued receiving progress from the running backup:
The database row showed:
The processes were still running afterward:
Both processes stopped only after manual termination.