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

  1. Call PutInput(ctx, answer) with the pending user input first; only after waiting=false, call Run to resume the chain.
  2. Check IsWaiting() before Run and route to the 'await user input' path instead of failing.
  3. 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

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


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