vxcontrol/pentagi · error
subtask is waiting, put input first
Error message
subtask is waiting, put input first
What it means
Run requires the subtask to NOT be waiting: if the previous chain execution ended with PerformResultWaiting, the agent is blocked on user input and Run must not be re-invoked until that input is supplied via PutInput (which flips waiting back to false). The error is a sequencing guard on the subtask state machine.
Source
Thrown at backend/pkg/controller/subtask.go:300
if err != nil {
return fmt.Errorf("failed to put input for subtask %d: %w", stw.subtaskCtx.SubtaskID, err)
}
stw.mx.Lock()
defer stw.mx.Unlock()
stw.waiting = false
return nil
}
func (stw *subtaskWorker) Run(ctx context.Context) error {
if stw.IsCompleted() {
return fmt.Errorf("subtask has already completed")
}
if stw.IsWaiting() {
return fmt.Errorf("subtask is waiting, put input first")
}
if err := stw.SetStatus(ctx, database.SubtaskStatusRunning); err != nil {
stw.handleInterrupting(err)
return err
}
var (
taskID = stw.subtaskCtx.TaskID
subtaskID = stw.subtaskCtx.SubtaskID
msgChainID = stw.subtaskCtx.MsgChainID
)
if err := stw.subtaskCtx.Provider.EnsureChainConsistency(ctx, msgChainID); err != nil {
stw.handleInterrupting(err)
return fmt.Errorf("failed to ensure chain consistency for subtask %d: %w", subtaskID, err)
}
View on GitHub (pinned to ea665308ba)
Solutions
- Call PutInput(ctx, answer) with the pending user input first; only after waiting=false, call Run to resume the chain.
- Check IsWaiting() before Run and route to the 'await user input' path instead of failing.
- Fix automation that polls Run; subscribe to subtask status changes and resume only after input was accepted.
Example fix
// before
if err := worker.Run(ctx); err != nil {
return err
}
// after
if worker.IsWaiting() {
return fmt.Errorf("awaiting user input for subtask; call PutInput before Run")
}
return worker.Run(ctx) Defensive patterns
Strategy: validation
Validate before calling
// route waiting subtasks to the input path, not Run
if worker.IsWaiting() {
return fmt.Errorf("pending user input required")
}
return worker.Run(ctx) Try / catch
if err := worker.Run(ctx); err != nil {
if strings.Contains(err.Error(), "subtask is waiting, put input first") {
// notify the UI that a user answer is required
return ErrInputRequired
}
return err
} Prevention
- Model the lifecycle explicitly: Running → Waiting ⇒ require input before Run.
- Never poll Run blindly; drive transitions from perform results.
- UI resume buttons must submit the pending answer (PutInput), not call Run.
- Log state transitions to debug sequencing bugs.
When it happens
Trigger: Calling Run(ctx) while IsWaiting() is true — i.e. re-running a subtask that stopped to ask the user a question, before PutInput was called; also a first Run call racing with an early transition to Waiting.
Common situations: Retry loops that call Run on a fixed interval without checking IsWaiting; a UI 'resume' button that calls Run instead of first submitting the pending user answer.
Related errors
- subtask has already completed
- subtask is not waiting, run first
- flow %d has status %s: loading aborted: %w
- failed to set flow %d status: %w
- failed to finish assistant %d: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/acf2c9a4cdd8af93.
Report an issue: GitHub.