micro/go-micro · error
agent resume pending: unsupported agent implementation %T
Error message
agent resume pending: unsupported agent implementation %T
What it means
agent.ResumePending (agent/agent.go:355) drains all incomplete checkpointed runs, but like Pending it type-asserts to the internal *agentImpl. Any other Agent implementation triggers this error because resume needs unexported checkpoint state.
Source
Thrown at agent/agent.go:355
a, ok := ag.(*agentImpl)
if !ok {
return nil, fmt.Errorf("agent pending: unsupported agent implementation %T", ag)
}
return a.pending(ctx)
}
// ResumePending resumes every checkpointed agent run that has not completed
// yet, in the same oldest-first order returned by Pending.
//
// It is a convenience for service startup and recovery loops: after recreating
// an agent with the same checkpoint store, call ResumePending to drain the
// durable backlog without listing and resuming each run manually. If any run
// fails again, ResumePending stops and returns that run id with the error so
// callers can log, alert, or retry later without hiding the failing run.
func ResumePending(ctx context.Context, ag Agent) (string, error) {
a, ok := ag.(*agentImpl)
if !ok {
return "", fmt.Errorf("agent resume pending: unsupported agent implementation %T", ag)
}
runs, err := a.pending(ctx)
if err != nil {
return "", err
}
for _, run := range runs {
if _, err := a.resume(ctx, run.ID); err != nil {
return run.ID, err
}
}
return "", nil
}
func (a *agentImpl) ask(ctx context.Context, message, parentRunID string) (*Response, error) {
a.mu.Lock()
defer a.mu.Unlock()
if a.model == nil {View on GitHub (pinned to 24529f1404)
Solutions
- Pass the concrete agent instance created by the library to ResumePending
- Store the unwrapped agent before applying decorators and use it for resume operations
- Expose pending/resume through the wrapper by delegating to the concrete agent internally
- Replace custom Agent implementations with the library's constructor output
Example fix
// before
type tracedAgent struct{ agent.Agent }
runs, err := agent.ResumePending(ctx, tracedAgent{inner})
// after
runs, err := agent.ResumePending(ctx, inner) // concrete agent value
Defensive patterns
Strategy: type-guard
Type guard
func canResumePending(ag agent.Agent) bool {
_, ok := ag.(*concreteAgentType) // replace with the exported constructor's concrete type
return ok
} Try / catch
id, err := agent.ResumePending(ctx, ag)
if err != nil && strings.Contains(err.Error(), "unsupported agent implementation") {
return fmt.Errorf("ResumePending requires the concrete agent value: %w", err)
} Prevention
- Keep the raw agent value from the constructor for checkpoint operations
- Wrap behavior around, not in front of, checkpoint APIs
- In tests, use the real agent type instead of fakes for resume loops
When it happens
Trigger: Calling agent.ResumePending(ctx, ag) with a non-*agentImpl value: a decorated/wrapped agent, a custom Agent implementation, or a mock.
Common situations: Same as Pending: wrapper middleware, test doubles, or proxies that satisfy the Agent interface but are not the concrete internal type; often seen in startup recovery loops that drain durable backlog.
Related errors
- agent: ResumeStreamAsk unsupported by implementation
- agent: ResumeStreamAsk requires a checkpoint
- agent: checkpointed run not found
- agent: checkpointed run is terminal with status
- agent: checkpointed run is input-required; resume with Resum
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/139c641357254477.
Report an issue: GitHub.