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
- Check errors.Is(err, ErrNothingToLoad) and skip the subtask or start it from scratch rather than treating it as a hard failure.
- If the subtask should run, kick off its worker for the 'created' state instead of calling the load path again.
- Deduplicate LoadSubtasks calls so the same subtask is not loaded twice in one recovery pass.
- 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
- Always errors.Is against ErrNothingToLoad; it is an expected condition, not a bug.
- Deduplicate recovery passes so a subtask is loaded once per cycle.
- Start a subtask's worker immediately after creating its row.
- Track created-but-never-run subtasks with a metric/alert.
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
- unexpected subtask status: %s
- subtask %d has no msg chains: %w
- unsupported subtask status: %s
- flow %d has status %s: loading aborted: %w
- failed to set flow %d status: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/7d9ddedd8cf8e9da.
Report an issue: GitHub.