redux-saga/redux-saga · error

The task is no longer Running, it is ${str}. You can't chang

Error message

The task is no longer Running, it is ${str}. You can't change the status of a task once it is no longer running.

What it means

@redux-saga/testing-utils' mock tasks expose methods like setResult, cancel, and reject that mutate task state. These operations are only valid while the task status is RUNNING, so assertStatusRunning throws with the actual status (e.g. Cancelled, Aborted, Done) when you attempt to change a finished or cancelled mock task's status.

Source

Thrown at packages/testing-utils/src/index.js:47

        const clonedGen = cloneableGenerator(generatorFunc)(...args)
        history.forEach(({ method, arg }) => clonedGen[method](arg))
        return clonedGen
      },
      return: (value) => record('return', value),
      throw: (exception) => record('throw', exception),
    }

    if (typeof Symbol !== 'undefined') {
      cloneableGen[Symbol.iterator] = () => cloneableGen
    }

    return cloneableGen
  }

const assertStatusRunning = (status) => {
  if (status !== RUNNING) {
    const str = statusToStringMap[status]
    throw new Error(
      `The task is no longer Running, it is ${str}. You can't change the status of a task once it is no longer running.`,
    )
  }
}

export function createMockTask() {
  let status = RUNNING
  let taskResult
  let taskError

  return {
    [TASK]: true,
    isRunning: () => status === RUNNING,
    isCancelled: () => status === CANCELLED,
    isAborted: () => status === ABORTED,
    result: () => taskResult,
    error: () => taskError,
    cancel: () => {

View on GitHub (pinned to b603028ae2)

Solutions

  1. Create a fresh mock task with createMockTask() for each state transition in your test instead of reusing one.
  2. Set all needed results on the mock task before marking it cancelled/done, or don't set the non-running status until done driving it.
  3. Restructure the test so each saga outcome (resolve, reject, cancel) is asserted with its own task instance.
  4. Check task.status() before mutating to confirm it is still RUNNING.

Example fix

// before
const task = createMockTask()
task.cancel()
task.setResult(data) // throws: task is Cancelled
// after
const task = createMockTask()
task.setResult(data)
task.cancel()
Defensive patterns

Strategy: validation

Validate before calling

function assertMutableTask(task) {
  if (task.status() !== 'RUNNING') {
    throw new Error(`Mock task is ${task.status()}; create a new mock task to mutate`)
  }
}

Type guard

const isRunningMockTask = (task) => typeof task.status === 'function' && task.status() === 'RUNNING'

Try / catch

try {
  mockTask.setResult(value)
} catch (e) {
  if (e.message.includes('no longer Running')) {
    mockTask = createMockTask()
    mockTask.setResult(value)
  } else {
    throw e
  }
}

Prevention

When it happens

Trigger: Calling mockTask.setResult(value), mockTask.reject(error), or mockTask.cancel() on a mock task created by createMockTask after its status was set to a non-RUNNING value (Cancelled, Aborted, Done).

Common situations: Unit tests that resolve/reject a mock task and then try to resolve it again (e.g. in a second assertion); reusing a single mock task across test phases; accidentally cancelling a mock task and then attempting setResult.

Related errors


AI-assisted analysis of redux-saga/redux-saga@b603028ae2 (2026-09-01). Data as JSON: /api/errors/4805807f56eade1a. Report an issue: GitHub.