micro/go-micro · warning
ErrStreamingUnsupported
ErrStreamingUnsupported
Error message
ai: streaming unsupported
What it means
ErrStreamingUnsupported is a sentinel error returned by Model providers that implement Generate but do not support token streaming. It is documented for use with errors.Is so callers can distinguish a missing capability from transient provider failures and fall back to non-streaming Generate.
Source
Thrown at ai/model.go:160
}
type runInfoKey struct{}
// WithRunInfo attaches run info to ctx.
func WithRunInfo(ctx context.Context, r RunInfo) context.Context {
return context.WithValue(ctx, runInfoKey{}, r)
}
// RunInfoFrom returns the run info attached to ctx, and whether it was set.
func RunInfoFrom(ctx context.Context) (RunInfo, bool) {
r, ok := ctx.Value(runInfoKey{}).(RunInfo)
return r, ok
}
// ErrStreamingUnsupported is returned by providers that implement the Model
// interface but do not yet support token streaming. Use errors.Is so callers
// can distinguish an unsupported capability from transient provider failures.
var ErrStreamingUnsupported = errors.New("ai: streaming unsupported")
// Stream is the interface for streaming responses.
type Stream interface {
// Recv receives the next chunk of the response
Recv() (*Response, error)
// Close closes the stream
Close() error
}
// ToolHandler executes a tool call and returns its result. It mirrors a
// go-micro RPC handler — context first, a request in, a result out — so
// the same mental model carries over from services to tools.
type ToolHandler func(ctx context.Context, call ToolCall) ToolResult
// ToolWrapper wraps a ToolHandler to add behavior around execution —
// logging, metrics, retries, guardrails. It is the tool-side analog of
// client.CallWrapper and server.HandlerWrapper: a wrapper takes the next
// handler and returns a new one, and code before the next(...) call runsView on GitHub (pinned to 24529f1404)
Solutions
- Detect with errors.Is(err, ai.ErrStreamingUnsupported) and fall back to non-streaming Generate
- Use a provider/Model implementation that supports the Stream interface
- Gate streaming behind a per-provider capability flag in your config
Example fix
// before
stream, err := model.Stream(ctx, req)
// after
stream, err := model.Stream(ctx, req)
if errors.Is(err, ai.ErrStreamingUnsupported) {
resp, err := model.Generate(ctx, req) // fallback to non-streaming
} Defensive patterns
Strategy: fallback
Validate before calling
type streamChecker interface { Stream(context.Context, *ai.Request) (ai.Stream, error) }
// capability unknown until called; rely on errors.Is sentinel Try / catch
stream, err := model.Stream(ctx, req)
if errors.Is(err, ai.ErrStreamingUnsupported) {
resp, err := model.Generate(ctx, req) // non-streaming fallback
} Prevention
- Always use errors.Is(err, ai.ErrStreamingUnsupported), never string comparison
- Implement a streaming→non-streaming fallback in every streaming call path
- Track per-provider streaming support in config and choose models accordingly
When it happens
Trigger: Calling Stream on a Model whose implementation returns ErrStreamingUnsupported; the agent streaming path hitting a provider without stream support (e.g. TestProvider_StreamWithToolsFallsBack scenario).
Common situations: Swapping model providers (e.g. to a backend without streaming); using a mock or legacy provider; enabling streaming flags against providers that only support request/response.
Related errors
- agent: StreamAsk unsupported by implementation
- agent: ResumeStreamAsk unsupported by implementation
- ai model is nil
- agent: ResumeStreamAsk requires a checkpoint
- agent: checkpointed run not found
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/94b6658e05da9759.
Report an issue: GitHub.