vxcontrol/pentagi · warning

subtask %d has created yet: %w

Error message

subtask %d has created yet: %w

What it means

LoadSubtaskWorker returns this error (wrapping ErrNothingToLoad) when the subtask's persisted status is already SubtaskStatusCreated — meaning it was created but never advanced, so there is nothing new to load or resume. It is a sentinel-style condition, not an unexpected failure.

Source

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

	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{},
		subtaskCtx: &SubtaskContext{
			MsgChainID:         msgChains[0].ID,
			SubtaskID:          subtask.ID,

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check errors.Is(err, ErrNothingToLoad) and skip the subtask or start it from scratch rather than treating it as a hard failure.
  2. If the subtask should run, kick off its worker for the 'created' state instead of calling the load path again.
  3. Deduplicate LoadSubtasks calls so the same subtask is not loaded twice in one recovery pass.
  4. Audit the code path that creates subtasks to ensure workers are started immediately after insertion.

Example fix

// before
worker, err := LoadSubtaskWorker(ctx, taskCtx, subtask)
if err != nil {
    return err
}
// after
worker, err := LoadSubtaskWorker(ctx, taskCtx, subtask)
if err != nil {
    if errors.Is(err, ErrNothingToLoad) {
        return nil // nothing to resume; skip
    }
    return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

// skip subtasks already in created state before attempting load
if subtask.Status == database.SubtaskStatusCreated {
    return nil // nothing to load
}

Type guard

func IsNothingToLoad(err error) bool {
    return errors.Is(err, controller.ErrNothingToLoad)
}

Try / catch

worker, err := LoadSubtaskWorker(ctx, taskCtx, subtask)
if err != nil {
    if errors.Is(err, controller.ErrNothingToLoad) {
        log.Info("subtask already created, skipping", "id", subtask.ID)
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: LoadSubtasks encounters a subtask whose DB status is exactly 'created': a subtask was inserted but its worker never started, or a prior load attempt already reset it and no progress was made.

Common situations: Recovery scan after a crash finds freshly-created-but-never-run subtasks; double invocation of LoadSubtasks for the same subtask; a producer inserted the subtask row but crashed before starting the worker.

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


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