micro/go-micro · error

agent run %s is input-required; resume with ResumeInput

Error message

agent run %s is input-required; resume with ResumeInput

What it means

agent.Resume rejects runs that are paused in the "input-required" stage because a plain resume cannot satisfy the run's pending request for human input. The library requires the caller to use agent.ResumeInput, which appends the supplied human input to the original message and continues the same run. This prevents silently resuming a run whose last tool call was the built-in request_input tool without providing the requested data.

Source

Thrown at agent/checkpoint.go:91

		return nil, fmt.Errorf("agent resume: unsupported agent implementation %T", ag)
	}
	return a.resume(ctx, runID)
}

func (a *agentImpl) resume(ctx context.Context, runID string) (*Response, error) {
	if a.opts.Checkpoint == nil {
		return nil, fmt.Errorf("agent %s has no checkpoint configured", a.opts.Name)
	}
	run, ok, err := a.opts.Checkpoint.Load(ctx, runID)
	if err != nil {
		return nil, err
	}
	if !ok {
		return nil, fmt.Errorf("agent run %s not found", runID)
	}
	if run.Status == "paused" {
		if run.State.Stage == agentInputStep {
			return nil, fmt.Errorf("agent run %s is input-required; resume with ResumeInput", runID)
		}
		run.Status = "running"
		run.State.Stage = agentAskStep
	}
	if run.Status == "done" {
		var resp Response
		if err := json.Unmarshal(run.State.Data, &resp); err != nil {
			return nil, fmt.Errorf("agent run %s response decode: %w", runID, err)
		}
		return &resp, nil
	}
	if terminalAgentRunStatus(run.Status) {
		return nil, fmt.Errorf("agent run %s is terminal with status %q", runID, run.Status)
	}
	message := string(run.State.Data)
	parentID := run.ParentID
	a.mu.Lock()
	defer a.mu.Unlock()

View on GitHub (pinned to 24529f1404)

Solutions

  1. Call agent.ResumeInput(ctx, ag, runID, input) instead of agent.Resume, supplying the answer the agent requested.
  2. Inspect the paused run's state/stage (via the checkpoint store) to decide between Resume and ResumeInput in your orchestration code.
  3. Configure the agent to avoid request_input if human input is not expected, or route input-required pauses to a human-in-the-loop UI.

Example fix

// before
resp, err := agent.Resume(ctx, ag, runID) // run is paused awaiting input
// after
resp, err := agent.ResumeInput(ctx, ag, runID, "Yes, use the staging database")
Defensive patterns

Strategy: try-catch

Validate before calling

run, ok, _ := ckpt.Load(ctx, runID)
needsInput := ok && run.Status == "paused" && run.State.Stage == "input-required"

Try / catch

resp, err := agent.Resume(ctx, ag, runID)
if err != nil && strings.Contains(err.Error(), "input-required") {
    resp, err = agent.ResumeInput(ctx, ag, runID, answerFromUser)
}

Prevention

When it happens

Trigger: Calling agent.Resume on a run whose checkpoint has Status=="paused" and State.Stage==agentInputStep ("input-required"), i.e. the run ended its last turn by invoking the request_input tool.

Common situations: A workflow where the agent asked a clarifying question via request_input and the developer's automation retries Resume in a generic polling loop; mixing up Resume and ResumeInput in code that handles both approval-paused and input-paused runs.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/c5f39ce93807dbc3. Report an issue: GitHub.