vxcontrol/pentagi · error
unexpected subtask status: %s
Error message
unexpected subtask status: %s
What it means
LoadSubtaskWorker hits its default switch branch when the subtask's status is none of the handled values (processed/created handling above), i.e. an unrecognized or intentionally un-settable status (such as 'created' set via this path or a corrupted value). It returns the raw status string for diagnosis.
Source
Thrown at backend/pkg/controller/subtask.go:109
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,
SubtaskTitle: subtask.Title,
SubtaskDescription: subtask.Description,View on GitHub (pinned to ea665308ba)
Solutions
- Log the subtask ID and status value; confirm what the actual stored status is.
- Filter out terminal-status subtasks (finished/failed) before calling LoadSubtaskWorker.
- After a version upgrade, run all goose migrations and verify status enum values match database.SubtaskStatus* constants.
- Add an explicit case for any newly introduced status in the switch.
Example fix
// before
subtasks := taskCtx.DB.GetAllSubtasks(ctx)
for _, s := range subtasks {
LoadSubtaskWorker(ctx, taskCtx, s)
}
// after
subtasks := taskCtx.DB.GetAllSubtasks(ctx)
for _, s := range subtasks {
if s.Status == database.SubtaskStatusFinished || s.Status == database.SubtaskStatusFailed {
continue // skip terminal subtasks
}
LoadSubtaskWorker(ctx, taskCtx, s)
} Defensive patterns
Strategy: validation
Validate before calling
switch subtask.Status {
case database.SubtaskStatusProcessed, database.SubtaskStatusProcessing:
// ok to load
default:
return fmt.Errorf("skip subtask %d: unsupported status %q", subtask.ID, subtask.Status)
} Type guard
func IsLoadableStatus(s database.SubtaskStatus) bool {
switch s {
case database.SubtaskStatusProcessed, database.SubtaskStatusProcessing:
return true
}
return false
} Try / catch
if !IsLoadableStatus(subtask.Status) {
log.Warn("unexpected subtask status", "id", subtask.ID, "status", subtask.Status)
return nil // skip rather than propagate
}
worker, err := LoadSubtaskWorker(ctx, taskCtx, subtask)
if err != nil { return err } Prevention
- Filter terminal statuses (finished/failed) out before any resume/load pass.
- After enum changes, re-run migrations and verify stored values match constants.
- Never hand-edit status columns in the DB.
- When adding a status constant, update every switch over SubtaskStatus.
When it happens
Trigger: A subtask row has a status value outside the enumerated cases in LoadSubtaskWorker — e.g. status 'failed'/'finished' passed to a loader, or a status string from an older schema version not matching current constants.
Common situations: Loading subtasks after a version upgrade where the status enum changed; DB rows manually edited; a bug elsewhere set an unexpected status; passing finished subtasks through the resume path.
Related errors
- subtask %d has created yet: %w
- unsupported subtask status: %s
- flow %d has status %s: loading aborted: %w
- failed to set flow %d status: %w
- failed to update subtask %d status to created: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/fb50b22c0e346ccf.
Report an issue: GitHub.