gatsbyjs/gatsby · error · Error

An ID must be provided when ending a job

Error message

An ID must be provided when ending a job

What it means

The v1 jobs reducer's END_JOB case requires action.payload.id to identify which active job to complete. It throws immediately if id is falsy, before looking up the job, because there is no way to splice the right entry out of state.jobs.active or compute its runTime without it.

Source

Thrown at packages/gatsby/src/redux/reducers/jobs.ts:38

          ...action.payload,
          createdAt: Date.now(),
          plugin: action.plugin,
        })

        state.active[index] = mergedJob
        return state
      } else {
        state.active.push({
          ...action.payload,
          createdAt: Date.now(),
          plugin: action.plugin,
        })
        return state
      }
    }
    case `END_JOB`: {
      if (!action.payload.id) {
        throw new Error(`An ID must be provided when ending a job`)
      }
      const completedAt = Date.now()
      const index = _.findIndex(state.active, j => j.id === action.payload.id)
      if (index === -1) {
        throw new Error(oneLine`
          The plugin "${_.get(action, `plugin.name`, `anonymous`)}"
          tried to end a job with the id "${action.payload.id}"
          that either hasn't yet been created or has already been ended`)
      }
      const job = state.active.splice(index, 1)[0]
      state.done.push({
        ...job,
        completedAt,
        runTime: moment(completedAt).diff(moment(job.createdAt)),
      })

      return state
    }

View on GitHub (pinned to 8b06340921)

Solutions

  1. Pass the same `id` used at creation time to endJob.
  2. Track job ids in a map when you create them so they are available at completion.
  3. Migrate to createJobV2 (v2 API) which manages lifecycle via content digest.

Example fix

// before
actions.endJob({}) // forgot id
// after
actions.endJob({ id: jobId })
Defensive patterns

Strategy: validation

Validate before calling

function endJobSafe(actions, jobOrId) {
  const id = typeof jobOrId === 'string' ? jobOrId : jobOrId?.id
  if (!id) throw new Error('endJob: id required')
  return actions.endJob({ id })
}

Type guard

function hasJobId(x) {
  return typeof x === 'string' ? x.length > 0 : !!x?.id
}

Prevention

When it happens

Trigger: Dispatching an END_JOB action (typically via the internal actions.endJob helper) with a missing or empty payload.id. Reached when a plugin tries to mark a job complete without specifying which job.

Common situations: Custom/third-party plugin using the legacy endJob API without passing the original job id; refactoring that drops the id variable; race where the id variable is undefined at the call site.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/8d20988d7b381213. Report an issue: GitHub.