n8n-io/n8n · error · TaskCancelledError

Task was cancelled

Error message

Task was cancelled

What it means

TaskCancelledError is raised when the forked subprocess exited with SIGTERM_EXIT_CODE, meaning it received a termination signal and shut down cooperatively. This is distinct from TaskKilledError (SIGKILL) and TaskTimeoutError (still alive at the ceiling). The executor treats SIGTERM as an explicit cancellation rather than a crash.

Source

Thrown at packages/@n8n/task-runner-python/src/task_executor.py:234

        pipe_reader = PipeReader(read_conn.fileno(), read_conn)
        pipe_reader.start()

        try:
            try:
                process.start()
            except Exception as e:
                raise TaskSubprocessFailedError(-1, e)
            finally:
                write_conn.close()

            process.join(timeout=task_timeout)

            if process.is_alive():
                TaskExecutor.stop_process(process)
                raise TaskTimeoutError(task_timeout)

            if process.exitcode == SIGTERM_EXIT_CODE:
                raise TaskCancelledError()

            if process.exitcode == SIGKILL_EXIT_CODE:
                raise TaskKilledError()

            if process.exitcode != 0:
                assert process.exitcode is not None
                raise TaskSubprocessFailedError(process.exitcode)

            pipe_reader.join(timeout=task_timeout)

            if pipe_reader.is_alive():
                try:
                    read_conn.close()
                except Exception:
                    pass
                raise TaskResultReadError(
                    TimeoutError(f"Pipe reader timed out after {task_timeout}s")
                )

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Treat cancellation as expected: catch TaskCancelledError at the caller and surface a user-visible 'cancelled' status rather than a generic failure.
  2. If cancellations are unexpected, audit what is sending SIGTERM to the runner (orchestrator, deployment scripts, OOM killer is SIGKILL not SIGTERM so look elsewhere).
  3. Make user Python code responsive to signals by checking a cancellation flag or registering a SIGTERM handler that exits promptly, so cancellation finishes quickly instead of waiting for the kill timeout.
  4. Confirm the runner's stop_process escalation window (grace -> SIGTERM -> SIGKILL) is long enough for the task to release resources.
Defensive patterns

Strategy: try-catch

Try / catch

from n8n_task_runner.errors import TaskCancelledError
try:
    result = TaskExecutor.execute_process(proc, rc, wc, task_timeout, continue_on_fail=False)
except TaskCancelledError:
    # cancellation is expected during aborts; treat as soft stop
    return [], [], 0

Prevention

When it happens

Trigger: The task was cancelled mid-flight by an external SIGTERM: an operator or orchestrator (n8n execution abort, container stop, k8s pod termination) sent SIGTERM to the worker process group, or the parent runner invoked stop_process which escalates to SIGTERM before SIGKILL.

Common situations: User clicks 'Stop execution' on a running workflow whose Python task is in flight; the runner container is being drained/rolled; a higher-level timeout (e.g. workflow-level) cancels the task; a manual kill -TERM was issued against the worker PID.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/fdcb7c223eb2434d. Report an issue: GitHub.