micro/go-micro · error
agent resume input: unsupported agent implementation %T
Error message
agent resume input: unsupported agent implementation %T
What it means
agent.ResumeInput only works with the library's concrete *agentImpl; it type-asserts the passed Agent and returns this error for any other implementation. Custom Agent wrappers or decorators (e.g. middleware wrapping the agent) lose the concrete type and cannot be used for checkpointed human-input resume.
Source
Thrown at agent/checkpoint.go:122
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()
if a.model == nil {
a.setup()
}
return a.askLocked(ctx, run.ID, message, parentID, &run, false)
}
// ResumeInput resumes a checkpointed agent run that paused via the built-in
// request_input tool. The supplied input is appended to the original request so
// the same run can continue with durable checkpoint and completed tool history.
func ResumeInput(ctx context.Context, ag Agent, runID, input string) (*Response, error) {
a, ok := ag.(*agentImpl)
if !ok {
return nil, fmt.Errorf("agent resume input: unsupported agent implementation %T", ag)
}
return a.resumeInput(ctx, runID, input)
}
func (a *agentImpl) resumeInput(ctx context.Context, runID, input 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" || run.State.Stage != agentInputStep {
return nil, fmt.Errorf("agent run %s is not waiting for human input", runID)
}View on GitHub (pinned to 24529f1404)
Solutions
- Pass the original *agentImpl returned by the library's agent constructor, not a wrapper, to ResumeInput.
- Keep a reference to the unwrapped agent for checkpoint operations while using the wrapper only for Run.
- Add an Unwrap() Agent method to your decorator and unwrap before calling ResumeInput.
- Use agent.ResumeInput only with agents created by this package's constructor.
Example fix
// before
type loggingAgent struct{ agent.Agent } // fails assertion
resp, err := agent.ResumeInput(ctx, loggingAgent{ag}, runID, input)
// after
resp, err := agent.ResumeInput(ctx, ag, runID, input) // raw agent from constructor Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := ag.(*agentimpl.AgentImpl); !ok {
return errors.New("ResumeInput requires the library's concrete agent")
} Type guard
func resumableAgent(ag agent.Agent) bool {
_, ok := ag.(*agentimpl.AgentImpl) // concrete impl from this package
return ok
} Try / catch
resp, err := agent.ResumeInput(ctx, ag, runID, input)
if err != nil && strings.Contains(err.Error(), "unsupported agent implementation") {
// unwrap decorator and retry with the underlying agent
} Prevention
- Keep an unwrapped reference to agents created by the library constructor.
- If you decorate agents, expose Unwrap() and unwrap before checkpoint calls.
- Never bridge agents across incompatible packages.
When it happens
Trigger: Passing a wrapped/marshalled Agent (your own struct embedding agent.Agent, a decorator, or a different implementation) into agent.ResumeInput; the assertion ag.(*agentImpl) fails.
Common situations: Wrapping agents in telemetry/retry middleware that implements the Agent interface; using a mock/fake agent in code paths that later call ResumeInput; multi-library setups where two different Agent interfaces are bridged.
Related errors
- agent: ResumeStreamAsk unsupported by implementation
- agent pending: unsupported agent implementation %T
- agent resume pending: unsupported agent implementation %T
- agent resume: unsupported agent implementation %T
- agent: StreamAsk unsupported by implementation
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/65d42841cb7755a0.
Report an issue: GitHub.