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
- Pass the same `id` used at creation time to endJob.
- Track job ids in a map when you create them so they are available at completion.
- 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
- Keep a reference to the job id returned/used at creation.
- Migrate to the v2 job API which keys by content digest.
- Add boundary validation for any internal redux actions you wrap.
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
- An ID must be provided when creating or setting job
- The plugin "${_.get(action, `plugin.name`, `anonymous`)}" tr
- You must pass an object into setPluginStatus. What was passe
- generateImageSource must be a function
- If you encounter this error, it's probably a Gatsby internal
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/8d20988d7b381213.
Report an issue: GitHub.