router-for-me/CLIProxyAPI · error
ExecuteModelStream requires Stream=true
Error message
ExecuteModelStream requires Stream=true
What it means
Programmer error in the plugin/host model API: ExecuteModelStream() only performs streaming internal model requests, so calling it with ModelExecutionRequest{Stream: false} (the zero value) is rejected with a mode error. The non-streaming counterpart is ExecuteModel().
Source
Thrown at sdk/api/handlers/model_execution.go:124
SkipRouterPluginID: req.SkipRouterPluginID,
})
if errMsg != nil {
return ModelExecutionResponse{}, errMsg
}
return ModelExecutionResponse{
StatusCode: http.StatusOK,
Headers: cloneHeader(headers),
Body: cloneBytes(body),
}, nil
}
// ExecuteModelStream executes an internal streaming model request.
// Host model callbacks are non-recursive for their caller: when
// skip plugin IDs are set, that plugin's interceptors and router are skipped
// for the nested model execution while other plugins may still run.
func (h *BaseAPIHandler) ExecuteModelStream(ctx context.Context, req ModelExecutionRequest) (ModelExecutionStream, *interfaces.ErrorMessage) {
if !req.Stream {
return ModelExecutionStream{}, modelExecutionModeError("ExecuteModelStream requires Stream=true")
}
dataChan, headers, errChan := h.executeStreamWithAuthManagerFormats(ctx, req.EntryProtocol, req.ExitProtocol, req.Model, cloneBytes(req.Body), req.Alt, false, modelExecutionOptions{
Headers: req.Headers,
Query: req.Query,
InternalSource: true,
SkipInterceptorPluginID: req.SkipInterceptorPluginID,
SkipRouterPluginID: req.SkipRouterPluginID,
})
chunks, errMsg := prepareModelExecutionStream(ctx, dataChan, errChan)
if errMsg != nil {
return ModelExecutionStream{}, errMsg
}
return ModelExecutionStream{
StatusCode: http.StatusOK,
Headers: cloneHeader(headers),
Chunks: chunks,
}, nil
}View on GitHub (pinned to 78f0c4079e)
Solutions
- Set Stream: true in the request passed to ExecuteModelStream
- If you want a single buffered response, call ExecuteModel instead
Example fix
// before
stream, errMsg := h.ExecuteModelStream(ctx, ModelExecutionRequest{Model: name, Body: body})
// after
stream, errMsg := h.ExecuteModelStream(ctx, ModelExecutionRequest{Model: name, Body: body, Stream: true}) Defensive patterns
Strategy: validation
Validate before calling
if !req.Stream {
return nil, fmt.Errorf("use ExecuteModel for buffered responses; got Stream=false on ExecuteModelStream")
}
stream, errMsg := h.ExecuteModelStream(ctx, req) Type guard
func isStreamingExecution(req ModelExecutionRequest) bool {
return req.Stream
} Try / catch
stream, errMsg := h.ExecuteModelStream(ctx, req)
if errMsg != nil && strings.Contains(errMsg.Error(), "requires Stream=true") {
log.Error("programmer error: Stream flag not set for the streaming API")
} Prevention
- Remember Stream defaults to false — always set it explicitly for streaming calls
- Centralize request construction in one helper per mode to avoid flag drift
When it happens
Trigger: A plugin builds a ModelExecutionRequest without setting Stream (defaults false) and passes it to BaseAPIHandler.ExecuteModelStream.
Common situations: Forgetting to set Stream: true when constructing the request for the streaming API — the most common variant since false is the zero value.
Related errors
- ExecuteProtocolStreamWithAuthManager requires Stream=true
- ExecuteModel requires Stream=false
- ExecuteProtocolWithAuthManager requires Stream=false
- count must be a positive integer
- Codex live multipart body requires an sdp field
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/d006e064fc59a2a3.
Report an issue: GitHub.