semaphoreui/semaphore · error
task is not active
Error message
task is not active
What it means
ConfirmTask transitions a pending task to the confirmed state by looking it up in the in-memory task pool. When the task is not in the pool (nil) the comment notes it 'exists in database' but is not active locally — typically already finished, restarted, or evicted — so confirmation is refused with this error.
Solutions
- Check the task's current state before confirming; skip confirmation if it already finished
- Treat this as a benign race in idempotent clients — log and continue instead of failing hard
- Re-run/re-trigger the task if a fresh confirmation cycle is genuinely needed
- Verify only one server instance manages the task pool (or use a shared/stateful setup)
Defensive patterns
Strategy: try-catch
Validate before calling
// confirm only while task is pending
if tsk.Status != taskStatusPending { /* skip confirmation */ } Try / catch
if err := pool.ConfirmTask(taskID, ...); err != nil {
if strings.Contains(err.Error(), "task is not active") {
return nil // already finished/rejected; idempotent no-op
}
return err
} Prevention
- Make confirmation idempotent — ignore 'not active' for resolved tasks
- Avoid confirming the same task twice concurrently
- Route task management to the instance owning the task pool
- Re-fetch task state after server restarts
When it happens
Trigger: Calling ConfirmTask with a task ID whose in-memory representation has been removed: the task already ran/finished, the server restarted losing the pool, or the ID never belonged to an active task on this instance.
Common situations: Confirming a task twice (second call finds nothing active); delayed confirmation after the task timed out or completed; multi-instance setups where the task was scheduled on another node; server restart mid-workflow.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- task not found
- no runners available
- OIDC sign-in failed: invalid state. Try signing in again.
- err
- name can not be empty
AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07).
Data as JSON: /api/errors/81a56e90d2448484.
Report an issue: GitHub.
Appendix: source
Thrown at services/tasks/TaskPool.go:637
res := proj.MaxParallelTasks > 0 && p.state.ActiveCount(t.Task.ProjectID) >= proj.MaxParallelTasks
if res {
return true
}
return res
}
func (p *TaskPool) ConfirmTask(targetTask db.Task) error {
tsk, err := p.GetTask(targetTask.ID)
if err != nil {
return err
}
if tsk == nil { // task not active, but exists in database
return fmt.Errorf("task is not active")
}
tsk.SetStatus(task_logger.TaskConfirmed)
return nil
}
func (p *TaskPool) RejectTask(targetTask db.Task) error {
tsk, err := p.GetTask(targetTask.ID)
if err != nil {
return err
}
if tsk == nil { // task not active, but exists in database
return fmt.Errorf("task is not active")
}
View on GitHub (pinned to 1774ccb71a)