micro/go-micro · error
agent: ResumeStreamAsk unsupported by implementation
Error message
agent: ResumeStreamAsk unsupported by implementation
What it means
ResumeStreamAsk resumes a checkpointed agent run with streaming, but only for the concrete *agentImpl type. Any other Agent implementation causes this sentinel error because resume-from-checkpoint logic is implemented solely on agentImpl.
Source
Thrown at agent/stream.go:66
func StreamAsk(ctx context.Context, ag Agent, message string) (AgentStream, error) {
streamer, ok := ag.(interface {
StreamAsk(context.Context, string) (AgentStream, error)
})
if !ok {
return nil, errors.New("agent: StreamAsk unsupported by implementation")
}
return streamer.StreamAsk(ctx, message)
}
// ResumeStreamAsk resumes a checkpointed agent run and emits the same event
// shape as StreamAsk. Completed runs are streamed from the persisted response;
// unfinished runs continue from their checkpoint and emit tool events for any
// work that still needs to run. Tool calls already recorded as done in the
// checkpoint are reused by the agent checkpoint wrapper and are not re-executed.
func ResumeStreamAsk(ctx context.Context, ag Agent, runID string) (AgentStream, error) {
a, ok := ag.(*agentImpl)
if !ok {
return nil, errors.New("agent: ResumeStreamAsk unsupported by implementation")
}
return a.resumeStreamAsk(ctx, runID)
}
// StreamAsk runs tools like Ask, emits ToolStart/ToolEnd events as they execute,
// then emits chunks of the final answer followed by a Done event.
func (a *agentImpl) StreamAsk(ctx context.Context, message string) (AgentStream, error) {
streamCtx, cancel := context.WithCancel(ctx)
events := make(chan *StreamEvent, 16)
done := make(chan struct{})
s := &agentStream{events: events, done: done, cancel: cancel}
go func() {
defer close(events)
defer close(done)
resp, err := a.askWithStreamEvents(streamCtx, message, events)
if err != nil {
s.setErr(err)View on GitHub (pinned to 24529f1404)
Solutions
- Pass the original *agentImpl returned by the library's constructor (not a wrapper)
- Expose the underlying agent via a method like Unwrap() and resume on that
- Create the agent directly from the library so the concrete type is preserved
Example fix
// before
wrapped := loggingAgent{inner: ag}
stream, err := agent.ResumeStreamAsk(ctx, wrapped, runID) // fails
// after
stream, err := agent.ResumeStreamAsk(ctx, ag, runID) // pass the concrete *agentImpl Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := ag.(*agent.AgentImpl); !ok { /* resume unsupported */ } Type guard
func supportsResumeStream(ag agent.Agent) bool {
_, ok := ag.(*agent.AgentImpl) // concrete implementation check
return ok
} Try / catch
stream, err := agent.ResumeStreamAsk(ctx, ag, runID)
if err != nil && strings.Contains(err.Error(), "unsupported by implementation") {
return fmt.Errorf("resume requires the concrete agent implementation")
} Prevention
- Never wrap the agent when you need checkpoint resume; keep the *agentImpl handy
- Expose Unwrap() on decorators to reach the concrete agent
- Document that checkpoint resume only works with library-provided agents
When it happens
Trigger: Calling agent.ResumeStreamAsk(ctx, ag, runID) with an Agent that is not the library's *agentImpl concrete type (e.g. a wrapper, decorator, or custom implementation).
Common situations: Wrapping the agent in middleware/decorators that hide the concrete type; storing the agent behind a custom interface value; tests using mock agents.
Related errors
- agent resume pending: unsupported agent implementation %T
- agent: StreamAsk unsupported by implementation
- agent: ResumeStreamAsk requires a checkpoint
- agent: checkpointed run not found
- agent: checkpointed run is terminal with status
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/9be4e0d6821e9e4d.
Report an issue: GitHub.