Job and workflow statuses
The status names below are the authoritative set.
Task walkthrough: Job statuses and actions. This page is the full configuration and troubleshooting reference.
Every job carries exactly one status, and that status decides two things: what the job is doing right now, and which actions you are allowed to take against it. Statuses fall into families — held, waiting, running, pending-term, and terminal — and a job moves between them in a fixed order. This page lists every status, the family it belongs to, and the actions each one accepts.
The order a job moves through
A job does not sit in one "waiting" state. It passes down a chain of gates, and its status tells you which gate it is at right now. Each gate releases it to the next one; the job only starts once it has cleared them all.
Reading it:
- The order is fixed. A job at
WAIT_RESOURCE_DEPENDENCYhas already satisfied its start time, its predecessors and its thresholds. That is why the status is a useful diagnosis on its own — it names the first thing still unmet. WAIT_MACHINEis always checked, even when a job has no dependencies at all.- A conflict is re-checked at the last moment. A job cleared for dependencies can still be
diverted to
WAIT_JOB_CONFLICTjust before dispatch, if the job it must not run alongside started in the meantime. It returns to the queue once that job finishes. - Cancel and skip can happen from any waiting gate — those arrows are left off to keep the picture readable.
…_PENDING_TERMis not finished. The job has stopped, but completion processing is still running and dependents are not released yet.
Job statuses
Held
| Status | Meaning |
|---|---|
ON_HOLD | Held; won't run until released. |
Waiting
| Status | Meaning |
|---|---|
RELEASED | Released and eligible to proceed. |
WAIT_START_TIME | Waiting for its scheduled start time — or for its next attempt, if it failed with failure-retry budget left. In the retry case the job holds the failed attempt's exit code, and its dependents are still waiting. |
WAIT_JOB_DEPENDENCY | Waiting on a predecessor job. |
WAIT_THRESHOLD_DEPENDENCY | Waiting on a threshold value. |
WAIT_RESOURCE_DEPENDENCY | Waiting for enough of a resource to be free. Nothing is reserved here — the units are taken when the job is dispatched, so a job can pass this gate and then wait in WAIT_TO_START if another job takes the units first. See Thresholds and resources. |
WAIT_EXPRESSION_DEPENDENCY | Waiting on an expression dependency to render True. The expression is re-asked about once a second; False is the normal state of a gate that is not open yet, and an expression that cannot be evaluated moves the job to ON_HOLD with the cause recorded as its termination description. |
WAIT_JOB_CONFLICT | Waiting because of a conflict with another job. |
WAIT_MACHINE | Waiting for an agent/machine to be available. A specific-agent job holds here while its target agent is OFFLINE on a fresh status feed (universal agents also hold on BUSY/DRAINING/DISABLED), and proceeds once it's ONLINE. If the feed is stale or UNKNOWN, the specific-agent gate fails open (advances) so the scheduler can't deadlock on untrusted status. A legacy-group job holds here until the group has a member dispatch could route to, and does not fail open on a stale or UNKNOWN feed — see When a legacy group has no dispatch target. |
WAIT_TO_START / WAIT_TO_START_FORCED | Queued to start (forced = via Force Start). A job with a resource dependency also stays in WAIT_TO_START while the units it needs are taken; it is retried on every pass. A forced start does not take resource units at all. |
LATE_TO_START | Past its late-to-start threshold, not yet started. |
JOB_TO_BE_SKIPPED | Marked to be skipped but not yet resolved — a deferred skip. Reached either by an operator's Skip in a live workflow, or at build time from a frequency whose build status is toBeSkipped. No end time, and its dependents are not released yet. The engine resolves it to terminal SKIPPED in sequence once the job's own gates are satisfied. See the Skip note under Which actions a job status accepts. |
PRERUN_FAILED | The prerun command failed. |
Running
| Status | Meaning |
|---|---|
ATTEMPT_TO_START / START_ATTEMPTED / STILL_ATTEMPTING_START | Starting the job. |
PRERUN_ACTIVE | The prerun command is running. |
JOB_RUNNING | Running. |
JOB_RUNNING_TO_BE_TERMINATED | Running, marked to be terminated. The job holds here until the agent stops the process and reports its outcome — see Killing a job on a legacy (LSAM) agent. |
LATE_TO_FINISH | Running past its late-to-finish threshold. |
Exceeding Max Run Time is not a status
A job that runs past its Max Run Time is labelled, not transitioned. There is no
EXCEEDED_MAX_RUNTIME status: the job still reads JOB_RUNNING while it runs, then earns whatever
terminal status it would have earned anyway — including FINISHED_OK.
What you see instead is an Exceeded Max Run Time badge beside the status, and it stays visible after the job completes. That is the point of it being separate: a job that overran and then finished OK is exactly the case the status alone cannot show. The overrun is reported once per run, and the job is not stopped — see Exceeding Max Run Time for how to have it killed instead.
A job always reaches a terminal status
JOB_RUNNING is not somewhere a job can stay for ever. Three ways a run could end short of
reporting an outcome — it was cancelled underneath the platform, it timed out waiting to be picked
up, or it could not be delivered to an agent at all — used to leave the job reading JOB_RUNNING
indefinitely, with nothing to do but mark it by hand. All three now end the job FAILED, the
same place a kill or a relay failure puts it.
A job whose work was cancelled before it ever started is not eligible for a failure retry, even with retry budget left. It ran nothing, so there is nothing to retry — and a retry there would quietly undo an operator's cancel, which is the opposite of what was asked for. A job that did run and then failed retries as normal.
A long outage no longer fails a job that is still running. When a legacy LSAM agent's connection drops, the relay holds the job while it waits for the agent to come back. That hold used to give up after 30 minutes and fail the job — even though the job was still running on the agent, whose eventual completion was then discarded. The hold now lasts up to seven days, so an outage has to be genuinely long before a running job is written off, and the job's real outcome is the one you see. Meanwhile a job still held after a transient error is re-probed within about 24 minutes regardless of how long the hold is allowed to last.
Pending-term (transitional)
FINISHED_OK_PENDING_TERM · FAILED_PENDING_TERM · MARKED_FINISHED_OK_PENDING_TERM ·
MARKED_FAILED_PENDING_TERM · SKIPPED_PENDING_TERM · UNDER_REVIEW_PENDING_TERM ·
FIXED_PENDING_TERM — completed, completion processing in progress; dependents not yet released.
A job passes through one of these for about a second after you set its status by hand, as well as when it completes on its own. While it's there:
- The Status Update tab reads "Processing status change" rather than "No actions available" — there genuinely are no actions yet, but the job isn't finished either.
- The tab's action buttons, including Restart, are disabled while the panel is refreshing, so you can't fire an action against a status the platform has already moved past.
- The panel and the Jobs grid refresh themselves every couple of seconds until the status
settles, then drop back to their normal cadence. Earlier builds waited for the ordinary refresh
interval or a manual reload, which is why a marked job could appear stuck on
… Pending Term.
Marking a job and then immediately marking it again — Mark Finished OK followed straight away by Mark Failed — means the second action arrives while the first is still in pending-term. Wait for the status to settle; the actions reappear on their own.
Terminal
| Status | Meaning | Category |
|---|---|---|
FINISHED_OK / MARKED_FINISHED_OK | Completed OK (marked = set by a user) | Success |
FIXED | Marked fixed; treated as resolved | Success |
FAILED / MARKED_FAILED | Failed (marked = set by a user) | Failure |
INITIALIZATION_ERROR | Failed to initialize | Failure |
MISSED_START_TIME | Did not start by its Latest Start Offset. The deadline is measured from the job's schedule date, not from today, and it applies to a recurring job parked between runs as well — reaching it retires the rest of that job's cycle. Two exceptions: a job waiting for a failure retry ran already, so passing the deadline there ends FAILED instead; and a job in a held workflow is not ended at all while the hold is on. The deadline is checked only while the job waits for its start time, is queued to start, or waits on a conflict — see Where the deadline is checked. See also Scheduling and the run, Failure retries and Holding a workflow suspends the deadline | Failure |
CANCELLED | Cancelled | — |
SKIPPED | Skipped | — |
Under review (not terminal)
| Status | Meaning |
|---|---|
UNDER_REVIEW | A failed job an operator has flagged for review with Under Review. |
UNDER_REVIEW is not a final status, and it has two effects worth knowing:
- Dependents that wait for a failure are released. A dependent whose Condition is
failureoranytreats an under-review predecessor as failed, so recovery work can start. A dependent waiting forsuccesskeeps waiting. See Dependencies. - The workflow does not complete. A workflow completes only when every job is in a terminal
status, so one holding an
UNDER_REVIEWjob staysIN_PROCESS. To finish it, resolve the job — Mark Fixed, Restart, Skip, Cancel, Mark Finished OK or Mark Failed — or Close the workflow, which accepts under-review jobs.
Job status-group filter
In Processes → Job View, the Status(s) filter offers groups rather than the raw statuses above. Each expands to its constituent statuses for the query:
| Group | Includes |
|---|---|
| Held | ON_HOLD |
| Waiting | every waiting status |
| Running | every running status |
| Pending Term | every pending-term status |
| Succeeded | FINISHED_OK, MARKED_FINISHED_OK, SKIPPED, FIXED |
| Fixed | FIXED |
| Skipped | SKIPPED |
| Failed | FAILED, MARKED_FAILED, INITIALIZATION_ERROR, MISSED_START_TIME |
| Cancelled | CANCELLED |
| Under Review | UNDER_REVIEW |
Fixed and Skipped are selectable on their own. Both were previously reachable only folded into Succeeded, with no way to isolate either — which meant a run's skipped jobs could not be listed at all. They now appear as their own groups (under More, alongside Pending Term, Cancelled and Under Review), and Succeeded still includes them, so it keeps the meaning it always had.
Per-group counts are unchanged by that addition: a FIXED or SKIPPED job is still counted
under Succeeded, so the totals beside the filter don't shift and don't double-count.
The filter is a closed list of these group names, not a free-text field. Typing narrows to a matching group — including Fixed and Skipped now that both are entries — but a raw status that isn't one of these groups can't be typed in directly.
Workflow statuses
| Status | Meaning |
|---|---|
BUILDING | Listed in the status set and the Building filter group, but the build does not put an instance in it: a new instance starts as WAIT_TO_START, as ON_HOLD when it is built on hold, or as WAIT_CONTAINER_JOB for a sub-schedule. |
WAIT_TO_START | Built, waiting to start. |
WAIT_CONTAINER_JOB | Waiting on a container (nested workflow) job. |
IN_PROCESS | Running. |
ON_HOLD / PARENT_HOLD | Held by an operator / held because an ancestor workflow is held. |
STARTED_BY_USER | Started manually. |
COMPLETED / CANCELLED | Terminal. |
UNKNOWN | Indeterminate. |
Workflow status-group filter
In Processes → Workflow View, the Status(s) filter offers coarse groups rather than the raw statuses above. Each group expands to its constituent statuses:
| Group | Includes |
|---|---|
| Building | BUILDING |
| Waiting | WAIT_TO_START, WAIT_CONTAINER_JOB |
| In Process | IN_PROCESS, STARTED_BY_USER |
| Held | ON_HOLD, PARENT_HOLD |
| Completed | COMPLETED |
| Cancelled | CANCELLED |
UNKNOWN is intentionally ungrouped (not user-facing). Unlike the job query, the workflow API
filters by individual status only, so selecting a group expands to its statuses for the query.
Holding a nested hierarchy
Holding a workflow holds everything beneath it, however deep the nesting goes. Every sub-schedule
below a held workflow reads PARENT_HOLD, and none of their jobs is dispatched.
This used to reach exactly one level. A hold on a parent held its immediate sub-schedules, but a
sub-schedule of those kept running — so on a three-level design, holding the top stopped the middle
and left the bottom working. Each workflow now looks up its whole chain of ancestors rather than at
its immediate parent alone, so the nearest held ancestor at any depth puts it in PARENT_HOLD.
Four consequences are worth knowing:
- A release resumes the whole subtree.
PARENT_HOLDis derived from the ancestor chain, not stored as a decision, so it is re-evaluated continuously — releasing the ancestor lets everything below it resume without acting on each level. - A hold an operator placed directly is not overwritten. A workflow you set to
ON_HOLDstaysON_HOLDeven while an ancestor is also held, and only a Release on it clears it. It does not quietly becomePARENT_HOLDand get released along with the ancestor. - Held workflows still finish work already in flight. A hold stops new jobs starting; it does not stop a workflow completing. That matters most for a nested run: a held sub-schedule that could not complete would never resolve its container job, and the whole chain above it would wedge behind it.
- Jobs are blocked for the sweep in which the hold lands. A descendant reads its old status for a moment after an ancestor is held, so dispatch checks the ancestor chain itself rather than trusting the descendant's status.
A hold also suspends the start deadline, at every depth — a waiting job in a held workflow, or in
one held by an ancestor, is not ended as MISSED_START_TIME while the hold is on. The deadline does
not move, though, so a job whose Latest Start passed during the hold is ended on the first pass after
you release. See
Holding a workflow suspends the deadline.
Which actions a job status accepts
The runtime accepts 11 lifecycle actions per job status, aligned to the job-UI matrix (the UI offers only the actions a status accepts, so a user is never shown an action that would fail):
Actions surface in two places — the row action menu in a job list, and the Status Update tab
on a job's detail panel. Both are driven from the same list, so they offer the same actions for the
same status. Restart included: a CANCELLED or SKIPPED job, whose only applicable action is
Restart, offers it in both places rather than reporting that no actions are available.
The Status Update tab reads as a short form. Under Choose a new status: each action the job's status accepts is a button carrying its icon, with its description underneath — so you can read what an action does without hovering anything. The order matches the row menu's. A banner at the top notes that the same actions are also on the job's card in the workflow diagram and in the job row's menu.
Selecting one opens the same dialog the row menu opens, so the reason fields, Restart's Restart on Hold and Reset Retry Count options, and Force Start's warning are all there. The one difference: opened from this tab, the dialog stays open with the error shown if the action fails, rather than closing. Every action is unavailable while the job is being re-read, and when the status accepts none the tab says so. Delete is not offered here — it is a row action, not a status change.
| Action | Accepted when the job is… |
|---|---|
| Hold | A waiting/WAIT_* state, RELEASED, LATE_TO_START, WAIT_TO_START(_FORCED), or PRERUN_FAILED. |
| Release | ON_HOLD. |
| Cancel | A held, waiting, or non-running failed state — ON_HOLD, RELEASED, any WAIT_*, LATE_TO_START, WAIT_TO_START(_FORCED), PRERUN_FAILED, JOB_TO_BE_SKIPPED, MISSED_START_TIME, INITIALIZATION_ERROR, FAILED, MARKED_FAILED, or UNDER_REVIEW. Not a running job — use Kill there. |
| Kill | A running state: ATTEMPT_TO_START, START_ATTEMPTED, STILL_ATTEMPTING_START, PRERUN_ACTIVE, JOB_RUNNING, or LATE_TO_FINISH. Kill is the running-job counterpart to Cancel. For a job on a legacy agent, see Killing a job on a legacy (LSAM) agent. |
| Restart | A stopped/terminal state: FAILED, MARKED_FAILED, INITIALIZATION_ERROR, CANCELLED, SKIPPED, FINISHED_OK, MARKED_FINISHED_OK, FIXED, UNDER_REVIEW, or JOB_TO_BE_SKIPPED. The dialog offers Restart on Hold and Reset Retry Count — the latter selected by default, so a restart normally returns the job's failure-retry budget to full. |
| Force Start | A dependency/WAIT_* state, ON_HOLD, RELEASED, WAIT_START_TIME, WAIT_TO_START(_FORCED), LATE_TO_START, PRERUN_FAILED, MISSED_START_TIME, or JOB_TO_BE_SKIPPED. Refused when the target agent is marked, or when the job's legacy agent group has nothing to dispatch to — see When a legacy group has no dispatch target. |
| Skip | A waiting/WAIT_* state, ON_HOLD, RELEASED, LATE_TO_START, PRERUN_FAILED, MISSED_START_TIME, or a failed state (FAILED, MARKED_FAILED, INITIALIZATION_ERROR, UNDER_REVIEW). |
| Mark Fixed | FAILED, MARKED_FAILED, INITIALIZATION_ERROR, or UNDER_REVIEW. |
| Under Review | FAILED, MARKED_FAILED, or INITIALIZATION_ERROR. |
| Mark Finished OK | Broad manual override accepted from most non-terminal states (held, waiting, starting, running, failed, under review, MISSED_START_TIME, FIXED); forces a successful outcome so dependents proceed. |
| Mark Failed | Broad manual override accepted from most non-terminal states plus FINISHED_OK/MARKED_FINISHED_OK/FIXED; forces a failed outcome so dependents react. |
Container jobs: a running container job (a step whose body is a nested workflow) accepts Kill only — the Mark Finished OK / Mark Failed overrides are refused while it runs, because its outcome is driven entirely by the nested workflow.
Mark Finished OK and Mark Failed set the outcome the platform records, so dependents proceed or react. Neither sends a stop request: the process keeps running on the agent until it ends on its own. Only Kill stops the work.
So a job you mark and then restart can have two runs of the same program alive at once. If you need the work to stop as well as the status to move, Kill it first and mark it afterwards.
The restarted run is not affected by the one it replaced. When the earlier run does finish, its result is discarded rather than applied to the job — it belongs to a run that has been superseded. Earlier builds could let it finish the new run, so a restart appeared to complete in seconds with the old run's outcome.
Skip is deferred and in-sequence — and a frequency can start it, not just an operator. A job whose winning frequency carries the build status
toBeSkippedis now built intoJOB_TO_BE_SKIPPEDand goes through exactly the same deferred resolution described below. Earlier builds created it already-terminal asSKIPPED, which released its dependents at once and let them complete even when the predecessor they actually depended on had failed. A frequency-driven mark whose gates never open parks indefinitely rather than letting the workflow finish past it. See Scheduling and the run.Skip is deferred and in-sequence. Skipping a job in a live workflow no longer takes effect immediately. The job is marked
JOB_TO_BE_SKIPPED(no end time, dependents still waiting), and the engine resolves it to terminalSKIPPEDin sequence — once the job's own TIME/JOB/THRESHOLD/ RESOURCE gates are satisfied, i.e. when it would otherwise have been its turn to start (SKIPPED_PENDING_TERM → SKIPPED, which stamps the end time and releases dependents). A job that has already reached that point — aFAILEDorMISSED_START_TIMEjob past its start window — resolves promptly. The skip is written terminal immediately only when the workflow is already terminal or the job isn't resident in the running graph (the in-sequence sweep could never reach it); a residual mark on a workflow being cancelled or closed is finalized toSKIPPEDas part of that action. AJOB_TO_BE_SKIPPEDmark does not block a workflow close, and it never reopens a finished workflow.
Killing a job on a legacy (LSAM) agent
Kill now reaches the agent that actually holds the process. Until this build, a Kill on a job
running on a legacy LSAM machine recorded your intent and stopped there: the job moved to
JOB_RUNNING_TO_BE_TERMINATED and stayed there for as long as the job kept running, because nothing
carried the request down to the machine. The job ran to completion regardless.
The request now travels to the machine over the relay's heartbeat:
What that means in practice:
- It is not instant. The kill waits for the relay's next heartbeat, so allow up to one heartbeat
interval — around 30 seconds by default — before the process stops. The job reads
JOB_RUNNING_TO_BE_TERMINATEDin the meantime. - A killed job reports
FAILED. There is no kill-specific outcome and no separate "killed" status: the agent reports the process's own termination and the platform records the job as failed. - You can Kill a job that hasn't reached the machine yet. A job reads
JOB_RUNNINGfrom the moment it is dispatched, which can be well before a busy or offline relay picks the work up. The kill is held and applied on the first heartbeat after the relay takes the job — so it lands rather than being refused and forgotten. - Killing twice is safe. A second Kill on the same job is accepted and changes nothing.
- A kill the agent can't act on is retried, not dropped. If the relay is down, or the agent refuses the stop, the request is offered again on every heartbeat until it is acted on.
- Restarting a killed job doesn't re-kill it. The kill applies to the run you issued it against, and is cleared when that job is run again.
- A platform restart no longer strands it. A job being killed is picked up again when the
platform's runtime restarts, so the agent's outcome is still collected and the job reaches its
terminal status. Earlier builds did not re-follow a job in
JOB_RUNNING_TO_BE_TERMINATEDafter a restart, and such a job sat in that status indefinitely even though the agent had already stopped the process and reported the result. A kill is still never re-judged by exit criteria.
If the request can't be recorded at all — an outage between the platform and its own agent service —
the job still moves to JOB_RUNNING_TO_BE_TERMINATED and the action still reports success, but
nothing is holding the kill to retry. If a job sits in that status well past a heartbeat interval,
issue Kill again.
When an action lands mid-dispatch
An action you take by hand and the platform's own dispatch pass can reach the same job at the same moment. When that happens, the action is refused as a conflict you can retry rather than being applied over the top of a dispatch already in progress.
Kill is the case you're most likely to see. A job still reading WAIT_TO_START,
WAIT_TO_START_FORCED, or LATE_TO_START looks like it hasn't started — but if the platform is
already dispatching it, Kill reports that the operation is in flight and asks you to retry,
instead of reporting that the action is invalid for the status. The distinction matters: the job isn't
ineligible, it's momentarily busy, and retrying a second later works.
Cancelling a workflow behaves the same way toward its jobs. The cascade that cancels a workflow's
running jobs now takes each job in turn and skips any the dispatch pass is holding, and it re-reads
each job before writing — so a job that reached its own outcome in the meantime keeps that outcome
instead of being overwritten with CANCELLED.
Workflow actions. The UI offers, per workflow-instance status:
| Workflow status | UI actions |
|---|---|
WAIT_TO_START | Hold · Start |
ON_HOLD | Release · Start |
IN_PROCESS | Hold · Close |
STARTED_BY_USER | Hold · Close |
COMPLETED | Hold · Release · Start — each one reopens the finished run (see below) |
WAIT_CONTAINER_JOB, PARENT_HOLD, BUILDING, CANCELLED, UNKNOWN | (none) |
- Start force-starts a built-but-not-yet-running instance now, ignoring its scheduled start time
(moves it to
STARTED_BY_USER, which is sweep-eligible and promotes toIN_PROCESS). - Release returns an
ON_HOLDinstance to the queue. An instance that has already run once resumes immediately — it does not fall back behind its original planned start time. That matters after a force-start: start a workflow early, hold it, release it, and it picks up where it left off rather than stalling until the time it was originally scheduled for. An instance that has never run still waits for its planned start time, which is the point of holding it. - Close force-completes an instance that is
IN_PROCESS, or one sitting inSTARTED_BY_USERafter a Start reopen. It succeeds only once the remaining jobs are all failed/under-review, and can't be undone. Because that blocking-job check still applies, Close on an ordinary force-start is refused — that instance's jobs are still waiting — so in practiceSTARTED_BY_USERis closeable only for a reopened run with nothing revived on it. A refusal names both statuses. - Cancel is retained as an event/programmatic endpoint but is not surfaced in the UI menu;
it's accepted on any non-terminal status. Cancel is not accepted on
COMPLETED, which the three reopen actions are — closing and cancelling a completed instance stay rejected the way any other terminal status rejects them. - Delete (soft-delete of the instance + its child jobs) is allowed from
WAIT_TO_START,WAIT_CONTAINER_JOB,ON_HOLD,PARENT_HOLD,COMPLETED, orCANCELLED— blocked while actively running (BUILDING,IN_PROCESS,STARTED_BY_USER,UNKNOWN). Delete is a manual intervention, not a lifecycle action.
Reopening a completed workflow
Hold, Release and Start are offered on a COMPLETED workflow instance, and each one
reopens the finished run rather than acting on a live one. Where the instance lands depends on
which action you take:
Action on a COMPLETED instance | Reopens it to |
|---|---|
| Hold | ON_HOLD |
| Release | WAIT_TO_START |
| Start | STARTED_BY_USER |
Reopening clears the recorded end time and asks you to confirm first — a single row raises a Reopen Completed Workflow confirmation naming the instance and where the action will leave it, and a bulk action over a selection containing completed rows confirms how many of them will reopen.
Nothing runs on the reopen alone. None of the three actions revives a job, so the instance rests
in its reopened status and is pinned there — it is deliberately not promoted to IN_PROCESS, and it
does not re-complete itself either. That pin lifts only once you Restart (or otherwise revive) a
job on it. From WAIT_TO_START or STARTED_BY_USER the instance then moves to IN_PROCESS on its
own; reopened with Hold it still needs a Release as well, the same as any held instance. Once
it does run on, it is a genuine second run: when it finishes, its completion events fire again rather
than being suppressed as a duplicate of the first run. The pin is recorded on the instance, so it
survives a service restart in the window between the reopen and the job.
Start reopen has only two exitsSTARTED_BY_USER is not a deletable status, so an instance reopened with Start and left with
nothing revived can only be moved on by restarting a job on it or by Close, which is exactly why
Close is accepted from that status. Reopening with Hold or Release instead leaves the instance
in a status you can still delete.
Two limits on reopening:
- A nested sub-schedule cannot be reopened. Hold, Release and Start are unavailable on a completed sub-schedule row — a sub-schedule's lifecycle is driven by its parent container job — and the API refuses the call. A bulk selection that includes a completed sub-schedule drops the three actions from its menu rather than partially failing.
- Age doesn't matter. A run that completed before the last service restart reopens the same way as one that finished minutes ago; the instance is loaded back into the runtime on demand.
Reopening also changes what an unattended rebuild will replace — see What an unattended rebuild will and won't replace.
Workflow actions that report success without changing anything
Three cases return success and leave the instance exactly as it was, rather than reporting the action as invalid:
- Hold, Release or Start on a sub-schedule in
WAIT_CONTAINER_JOBorPARENT_HOLD. These states belong to the parent container job, so an operator action on the sub-schedule has nothing to apply — it is accepted and ignored. - Release on an instance that is already
WAIT_TO_START. - Start on an instance that is already
STARTED_BY_USER.
Hold on an already-ON_HOLD instance behaves the same way, as it always has.