vxcontrol/pentagi · error

failed to update subtask %d status to created: %w

Error message

failed to update subtask %d status to created: %w

What it means

LoadSubtaskWorker resets a subtask stuck in a non-Created state (e.g. 'processing' after a crash) back to SubtaskStatusCreated via UpdateSubtaskStatus. This error wraps a failure of that status-reset UPDATE, identified by subtask ID. It indicates the resume/recovery path could not normalize the subtask state.

Source

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

	ctx, span := obs.Observer.NewSpan(ctx, obs.SpanKindInternal, "controller.LoadSubtaskWorker")
	defer span.End()

	var completed, waiting bool
	switch subtask.Status {
	case database.SubtaskStatusFinished, database.SubtaskStatusFailed:
		completed = true
	case database.SubtaskStatusWaiting:
		waiting = true
	case database.SubtaskStatusRunning:
		var err error
		// if subtask is running, it means that it was not finished by previous run
		// so we need to set it to created and continue from the beginning
		subtask, err = taskCtx.DB.UpdateSubtaskStatus(ctx, database.UpdateSubtaskStatusParams{
			Status: database.SubtaskStatusCreated,
			ID:     subtask.ID,
		})
		if err != nil {
			return nil, fmt.Errorf("failed to update subtask %d status to created: %w", subtask.ID, err)
		}
	case database.SubtaskStatusCreated:
		return nil, fmt.Errorf("subtask %d has created yet: %w", subtask.ID, ErrNothingToLoad)
	default:
		return nil, fmt.Errorf("unexpected subtask status: %s", subtask.Status)
	}

	msgChains, err := taskCtx.DB.GetSubtaskPrimaryMsgChains(ctx, database.Int64ToNullInt64(&subtask.ID))
	if err != nil {
		return nil, fmt.Errorf("failed to get subtask primary msg chains for subtask %d: %w", subtask.ID, err)
	}

	if len(msgChains) == 0 {
		return nil, fmt.Errorf("subtask %d has no msg chains: %w", subtask.ID, ErrNothingToLoad)
	}

	return &subtaskWorker{
		mx: &sync.RWMutex{},

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check DB connectivity and retry LoadSubtasks once the database is reachable.
  2. Inspect the wrapped cause for lock timeouts (deadlocks/row locks) and reduce concurrent reload of the same subtask.
  3. Verify the subtask row still exists; if deleted, remove it from the load queue instead of retrying.
  4. Ensure all goose migrations ran so status enums/columns match the code's expectations.

Example fix

// before
workers, err := LoadSubtasks(ctx, taskCtx)
if err != nil {
    return err
}
// after
workers, err := LoadSubtasks(ctx, taskCtx)
if err != nil {
    if isRetryableDBError(err) {
        time.Sleep(backoff)
        workers, err = LoadSubtasks(ctx, taskCtx)
    }
    if err != nil {
        return fmt.Errorf("load subtasks after restart: %w", err)
    }
}
Defensive patterns

Strategy: retry

Validate before calling

// before recovery load, confirm the row is updatable and DB reachable
if err := db.PingContext(ctx); err != nil {
    return fmt.Errorf("db unavailable: %w", err)
}
var st string
err := db.QueryRowContext(ctx, `SELECT status FROM subtasks WHERE id=$1`, id).Scan(&st)
if err != nil { return err }

Type guard

func IsStatusResetFailure(err error) bool {
    return strings.Contains(err.Error(), "status to created")
}

Try / catch

worker, err := LoadSubtaskWorker(ctx, taskCtx, subtask)
if err != nil {
    if isTransientDBError(err) {
        return retryWithBackoff(ctx, func() error {
            _, err = LoadSubtaskWorker(ctx, taskCtx, subtask)
            return err
        })
    }
    return err
}

Prevention

When it happens

Trigger: Calling LoadSubtasks after restart for a subtask whose status was e.g. 'processing' when the DB UPDATE fails — DB down, row locked, row deleted concurrently, or constraint violation.

Common situations: Server crash left subtasks in 'processing'; on recovery the database is temporarily unavailable; concurrent workers race to reload the same subtask causing lock contention; migrations not applied so the status column value differs.

Related errors


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