vxcontrol/pentagi · warning
subtask %d has no msg chains: %w
Error message
subtask %d has no msg chains: %w
What it means
LoadSubtaskWorker requires at least one primary message chain to build a subtaskWorker; when GetSubtaskPrimaryMsgChains returns zero rows it wraps ErrNothingToLoad with the subtask ID. This signals the subtask has no conversation history to resume — the chain was never created or was deleted.
Source
Thrown at backend/pkg/controller/subtask.go:118
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,
SubtaskTitle: subtask.Title,
SubtaskDescription: subtask.Description,
TaskContext: *taskCtx,
},
updater: updater,
completed: completed,
waiting: waiting,
}, nil
}
func (stw *subtaskWorker) GetMsgChainID() int64 {View on GitHub (pinned to ea665308ba)
Solutions
- Check errors.Is(err, ErrNothingToLoad) and skip or re-initialize the subtask's chain instead of failing the batch.
- Verify chains were actually created for the subtask (query msg_chain by subtask ID).
- If chains were deleted intentionally, mark the subtask failed/finished rather than leaving it loadable.
- Fix ordering so a subtask's status only advances after its primary chain exists.
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) {
_ = taskCtx.DB.UpdateSubtaskStatus(ctx, database.UpdateSubtaskStatusParams{
Status: database.SubtaskStatusFailed, ID: subtask.ID,
})
return nil
}
return err
} Defensive patterns
Strategy: type-guard
Validate before calling
// confirm at least one primary chain exists before loading
var n int
err := db.QueryRowContext(ctx,
`SELECT COUNT(*) FROM msg_chain WHERE subtask_id=$1`, subtaskID).Scan(&n)
if err == nil && n == 0 {
return fmt.Errorf("subtask %d has no chains; mark failed instead", subtaskID)
} Type guard
func IsNoMsgChains(err error) bool {
return errors.Is(err, controller.ErrNothingToLoad) &&
strings.Contains(err.Error(), "no msg chains")
} Try / catch
worker, err := LoadSubtaskWorker(ctx, taskCtx, subtask)
if err != nil {
if errors.Is(err, controller.ErrNothingToLoad) {
_ = db.UpdateSubtaskStatus(ctx, database.UpdateSubtaskStatusParams{
Status: database.SubtaskStatusFailed, ID: subtask.ID})
return nil
}
return err
} Prevention
- Only advance a subtask's status after its primary msg chain is persisted (transactional create).
- Do not delete msg_chain rows while the owning subtask is still active.
- Treat ErrNothingToLoad as 'skip or finalize', never as a crash.
- Periodically scan for orphaned subtasks without chains and finalize them.
When it happens
Trigger: A subtask reached a non-initial status but has no primary msg chain rows — e.g. chain creation failed earlier (see error 142) yet the status advanced, or chains were deleted by cleanup while the subtask row remained.
Common situations: Partial failure between chain creation and status update; manual DB cleanup removing msg_chain rows; recovery scan picking up orphaned subtasks; bug in chain-per-subtask bookkeeping.
Related errors
- subtask %d has created yet: %w
- failed to get subtask primary msg chains for subtask %d: %w
- failed to update subtask %d status to created: %w
- unexpected subtask status: %s
- failed to set subtask %d status: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/e2395c35dafb97cc.
Report an issue: GitHub.