{"record":{"id":"94b6658e05da9759","repo":"micro/go-micro","slug":"errstreamingunsupported","errorCode":"ErrStreamingUnsupported","errorMessage":"ai: streaming unsupported","messagePattern":"ai: streaming unsupported","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"ai/model.go","lineNumber":160,"sourceCode":"}\n\ntype runInfoKey struct{}\n\n// WithRunInfo attaches run info to ctx.\nfunc WithRunInfo(ctx context.Context, r RunInfo) context.Context {\n\treturn context.WithValue(ctx, runInfoKey{}, r)\n}\n\n// RunInfoFrom returns the run info attached to ctx, and whether it was set.\nfunc RunInfoFrom(ctx context.Context) (RunInfo, bool) {\n\tr, ok := ctx.Value(runInfoKey{}).(RunInfo)\n\treturn r, ok\n}\n\n// ErrStreamingUnsupported is returned by providers that implement the Model\n// interface but do not yet support token streaming. Use errors.Is so callers\n// can distinguish an unsupported capability from transient provider failures.\nvar ErrStreamingUnsupported = errors.New(\"ai: streaming unsupported\")\n\n// Stream is the interface for streaming responses.\ntype Stream interface {\n\t// Recv receives the next chunk of the response\n\tRecv() (*Response, error)\n\t// Close closes the stream\n\tClose() error\n}\n\n// ToolHandler executes a tool call and returns its result. It mirrors a\n// go-micro RPC handler — context first, a request in, a result out — so\n// the same mental model carries over from services to tools.\ntype ToolHandler func(ctx context.Context, call ToolCall) ToolResult\n\n// ToolWrapper wraps a ToolHandler to add behavior around execution —\n// logging, metrics, retries, guardrails. It is the tool-side analog of\n// client.CallWrapper and server.HandlerWrapper: a wrapper takes the next\n// handler and returns a new one, and code before the next(...) call runs","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/model.go#L142-L178","documentation":"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.","triggerScenarios":"Calling Stream on a Model whose implementation returns ErrStreamingUnsupported; the agent streaming path hitting a provider without stream support (e.g. TestProvider_StreamWithToolsFallsBack scenario).","commonSituations":"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.","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"],"exampleFix":"// before\nstream, err := model.Stream(ctx, req)\n// after\nstream, err := model.Stream(ctx, req)\nif errors.Is(err, ai.ErrStreamingUnsupported) {\n    resp, err := model.Generate(ctx, req) // fallback to non-streaming\n}","handlingStrategy":"fallback","validationCode":"type streamChecker interface { Stream(context.Context, *ai.Request) (ai.Stream, error) }\n// capability unknown until called; rely on errors.Is sentinel","typeGuard":null,"tryCatchPattern":"stream, err := model.Stream(ctx, req)\nif errors.Is(err, ai.ErrStreamingUnsupported) {\n    resp, err := model.Generate(ctx, req) // non-streaming fallback\n}","preventionTips":["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"],"tags":["go","ai","streaming","fallback","capability"],"backgroundTag":"operation-not-supported","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}