micro/go-micro · error

agent resume: unsupported agent implementation %T

Error message

agent resume: unsupported agent implementation %T

What it means

The package-level agent.Resume (agent/checkpoint.go:73) returns the response for a checkpointed run, but it only accepts the internal *agentImpl concrete type. Any other Agent implementation fails this type assertion and gets this error, since resume needs unexported checkpoint state.

Source

Thrown at agent/checkpoint.go:73

		stage := run.State.Stage
		if stage == "" && len(run.Steps) > 0 {
			stage = run.Steps[0].Name
		}
		a.recordTimelineEvent(ctx, RunEvent{
			Time: time.Now(), RunID: info.RunID, ParentID: info.ParentID, Agent: info.Agent,
			Kind: "checkpoint", Name: stage, Status: run.Status,
		})
	}
	return nil
}

// Resume returns the response for a checkpointed agent run. Completed runs are
// returned from the checkpoint without calling the model or replaying tool
// calls; failed or in-progress runs continue from the saved input message.
func Resume(ctx context.Context, ag Agent, runID string) (*Response, error) {
	a, ok := ag.(*agentImpl)
	if !ok {
		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)

View on GitHub (pinned to 24529f1404)

Solutions

  1. Pass the original concrete agent (not a wrapper) to Resume
  2. Keep the unwrapped agent reference before decorating and use it for Resume calls
  3. Delegate resume inside your wrapper to the concrete agent's Resume
  4. Use the library's agent constructor output directly instead of custom Agent implementations

Example fix

// before
var ag agent.Agent = withTracing(agent.New(...))
resp, err := agent.Resume(ctx, ag, runID) // unsupported
// after
concrete := agent.New(...)
resp, err := agent.Resume(ctx, concrete, runID)
Defensive patterns

Strategy: type-guard

Type guard

func supportsResume(ag agent.Agent) bool {
    _, ok := ag.(*concreteAgentType) // the type returned by the library constructor
    return ok
}

Try / catch

resp, err := agent.Resume(ctx, ag, runID)
if err != nil && strings.Contains(err.Error(), "unsupported agent implementation") {
    return fmt.Errorf("Resume needs the concrete agent, not a wrapper: %w", err)
}

Prevention

When it happens

Trigger: Calling agent.Resume(ctx, ag, runID) where ag is a wrapped, decorated, mocked, or otherwise custom Agent rather than the concrete agent value produced by the library.

Common situations: Passing a logging/tracing wrapper into resume flows in tests or recovery loops; using a fake Agent in unit tests like the ones listed; mixing agent implementations across package versions.

Related errors


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