vxcontrol/pentagi · error

failed to set subtask %d status to failed: %w

Error message

failed to set subtask %d status to failed: %w

What it means

Wraps the error from subtaskWorker.SetStatus when the worker tried to mark a subtask as 'failed' after the agent chain reported PerformResultError. The status write itself failed, so the subtask may remain Running instead of Failed, leaving the flow in an inconsistent state. handleInterrupting resets the subtask to Waiting only when the underlying error is a context interruption.

Source

Thrown at backend/pkg/controller/subtask.go:346

		_ = stw.SetStatus(ctx, database.SubtaskStatusWaiting)
		return fmt.Errorf("failed to perform agent chain for subtask %d: %w", subtaskID, err)
	}

	switch performResult {
	case providers.PerformResultWaiting:
		if err := stw.SetStatus(ctx, database.SubtaskStatusWaiting); err != nil {
			stw.handleInterrupting(err)
			return err
		}
	case providers.PerformResultDone:
		if err := stw.SetStatus(ctx, database.SubtaskStatusFinished); err != nil {
			stw.handleInterrupting(err)
			return fmt.Errorf("failed to set subtask %d status to finished: %w", subtaskID, err)
		}
	case providers.PerformResultError:
		if err := stw.SetStatus(ctx, database.SubtaskStatusFailed); err != nil {
			stw.handleInterrupting(err)
			return fmt.Errorf("failed to set subtask %d status to failed: %w", subtaskID, err)
		}
	default:
		return fmt.Errorf("unknown perform result: %d", performResult)
	}

	return nil
}

// handleInterrupting sets this subtask (and task/flow via SetStatus back-propagation)
// to Waiting when err is context.Canceled or context.DeadlineExceeded. Use after the subtask
// was advanced past Waiting (e.g. Running) but the run aborts before PerformAgentChain's
// normal error handler, or when a late SetStatus fails with a context interruption.
func (stw *subtaskWorker) handleInterrupting(err error) {
	if err == nil {
		return
	}
	if !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) {
		return

View on GitHub (pinned to ea665308ba)

Solutions

  1. Inspect the wrapped root error for the DB failure and restore DB connectivity, then reload the flow — LoadSubtasks will pick the subtask up in its persisted state.
  2. If the cause is context cancellation, the worker already reset the subtask to Waiting; re-run the flow or the subtask.
  3. Check for concurrent status writers (flow cancellation + worker SetStatus racing) and ensure only the worker mutates subtask status.
  4. If the subtask is stuck in 'running' in the DB, use the interrupt/reset path or manually reset it to created/waiting before retrying.

Example fix

// before: ignoring the error, leaving subtask stuck running
_ = stw.Run(ctx)
// after: handle and verify state before retrying
if err := stw.Run(ctx); err != nil {
    logrus.WithError(err).Error("subtask run failed")
    // reload from DB to see actual persisted status before retrying
    stc.LoadSubtasks(ctx, taskID, updater)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if stw.IsCompleted() { return nil }
if err := db.PingContext(ctx); err != nil { return err }

Type guard

func isInterrupting(err error) bool {
    return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
}

Try / catch

if err := stw.Run(ctx); err != nil {
    logrus.WithError(err).WithField("subtask_id", id).Error("subtask run failed")
    // reload persisted state to learn the true status before any retry
    _ = stc.LoadSubtasks(ctx, taskID, updater)
}

Prevention

When it happens

Trigger: subtaskWorker.Run() receives providers.PerformResultError from PerformAgentChain and SetStatus(ctx, SubtaskStatusFailed) fails — context canceled during the update, DB unreachable, or the subtask row was concurrently changed.

Common situations: Agent tool execution fails (e.g. Docker container error) at the same moment the user cancels the flow; DB connection pool exhaustion; the task was deleted concurrently; repeated failures during a Postgres failover.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/0fbd973de2ee30de. Report an issue: GitHub.