# Task Model

This page explains what a go-scheduler task holds and which states it moves through.

## Task Fields

A task registered with `Add` holds a schedule, an action, a description, an execution limit, a timeout callback, and a prerequisite list, and receives an increasing `int64` ID from `atomic.AddInt64`.

| Action type | Initial state | Dependencies allowed | Failure sources |
|---|---|---|---|
| `func()` | `TaskCompleted` | No, `Add` returns an error | panic (when no execution limit is set), timeout |
| `func() error` | `TaskPending` | Yes | returned error, panic (when no execution limit is set), timeout |

A panic is recovered and recorded as `TaskFailed` only when the task has no execution limit. With a `time.Duration` limit the action runs in its own goroutine without `recover`, so a panic terminates the process; see [Timeouts](/core-concepts-timeouts#timeout-behavior).

## Task States

```go
const (
	TaskPending int = iota
	TaskRunning
	TaskCompleted
	TaskFailed
)
```

| Transition | Trigger |
|---|---|
| `TaskPending` → `TaskRunning` | Fire time reached and dependencies (if any) satisfied |
| `TaskRunning` → `TaskCompleted` | Action returns normally |
| `TaskRunning` → `TaskFailed` | Returned error, recovered panic, or execution limit exceeded |
| `TaskPending` → `TaskFailed` | Prerequisite failed (`Stop`), prerequisite missing, or wait timeout |
| `TaskCompleted` / `TaskFailed` → `TaskRunning` | Next trigger of a task without dependencies |

States never return to `TaskPending`. A task with dependencies skips later triggers while its state is `TaskRunning` or `TaskCompleted`; because the state stays `TaskCompleted` after a successful run, such a task completes at most once, while a `TaskFailed` dependent task is evaluated again on its next trigger.

## Related Topics

- [Schedule Syntax](/core-concepts-schedule) — cron fields, descriptors, and `@every`
- [Task Dependencies](/core-concepts-dependencies) — prerequisite policies and wait rules
- [Timeouts](/core-concepts-timeouts) — execution limits and timeout callbacks
- [Scheduler Lifecycle](/core-concepts-lifecycle) — how operations behave before and after `Start`
