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 runs

View on GitHub (pinned to 24529f1404)

Solutions

  1. Detect with errors.Is(err, ai.ErrStreamingUnsupported) and fall back to non-streaming Generate
  2. Use a provider/Model implementation that supports the Stream interface
  3. 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

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


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