{"record":{"id":"139c641357254477","repo":"micro/go-micro","slug":"agent-resume-pending-unsupported-agent-implementa","errorCode":null,"errorMessage":"agent resume pending: unsupported agent implementation %T","messagePattern":"agent resume pending: unsupported agent implementation %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/agent.go","lineNumber":355,"sourceCode":"\ta, ok := ag.(*agentImpl)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"agent pending: unsupported agent implementation %T\", ag)\n\t}\n\treturn a.pending(ctx)\n}\n\n// ResumePending resumes every checkpointed agent run that has not completed\n// yet, in the same oldest-first order returned by Pending.\n//\n// It is a convenience for service startup and recovery loops: after recreating\n// an agent with the same checkpoint store, call ResumePending to drain the\n// durable backlog without listing and resuming each run manually. If any run\n// fails again, ResumePending stops and returns that run id with the error so\n// callers can log, alert, or retry later without hiding the failing run.\nfunc ResumePending(ctx context.Context, ag Agent) (string, error) {\n\ta, ok := ag.(*agentImpl)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"agent resume pending: unsupported agent implementation %T\", ag)\n\t}\n\truns, err := a.pending(ctx)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tfor _, run := range runs {\n\t\tif _, err := a.resume(ctx, run.ID); err != nil {\n\t\t\treturn run.ID, err\n\t\t}\n\t}\n\treturn \"\", nil\n}\n\nfunc (a *agentImpl) ask(ctx context.Context, message, parentRunID string) (*Response, error) {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\n\tif a.model == nil {","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/agent/agent.go#L337-L373","documentation":"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.","triggerScenarios":"Calling agent.ResumePending(ctx, ag) with a non-*agentImpl value: a decorated/wrapped agent, a custom Agent implementation, or a mock.","commonSituations":"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.","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"],"exampleFix":"// before\ntype tracedAgent struct{ agent.Agent }\nruns, err := agent.ResumePending(ctx, tracedAgent{inner})\n// after\nruns, err := agent.ResumePending(ctx, inner) // concrete agent value\n","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func canResumePending(ag agent.Agent) bool {\n    _, ok := ag.(*concreteAgentType) // replace with the exported constructor's concrete type\n    return ok\n}","tryCatchPattern":"id, err := agent.ResumePending(ctx, ag)\nif err != nil && strings.Contains(err.Error(), \"unsupported agent implementation\") {\n    return fmt.Errorf(\"ResumePending requires the concrete agent value: %w\", err)\n}","preventionTips":["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"],"tags":["go","agent","type-assertion","checkpoint"],"backgroundTag":"unsupported-implementation-type","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}