{"record":{"id":"18b4cc0ddfa2b7e3","repo":"router-for-me/CLIProxyAPI","slug":"executemodel-requires-stream-false","errorCode":null,"errorMessage":"ExecuteModel requires Stream=false","messagePattern":"ExecuteModel requires Stream=false","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"sdk/api/handlers/model_execution.go","lineNumber":99,"sourceCode":"\n// Error returns the stream error message or the HTTP status text.\nfunc (e *ModelExecutionStreamError) Error() string {\n\tif e == nil {\n\t\treturn \"\"\n\t}\n\tif e.Message != \"\" {\n\t\treturn e.Message\n\t}\n\treturn http.StatusText(e.StatusCode)\n}\n\n// ExecuteModel executes an internal non-streaming model request.\n// Host model callbacks are non-recursive for their caller: when\n// skip plugin IDs are set, that plugin's interceptors and router are skipped\n// for the nested model execution while other plugins may still run.\nfunc (h *BaseAPIHandler) ExecuteModel(ctx context.Context, req ModelExecutionRequest) (ModelExecutionResponse, *interfaces.ErrorMessage) {\n\tif req.Stream {\n\t\treturn ModelExecutionResponse{}, modelExecutionModeError(\"ExecuteModel requires Stream=false\")\n\t}\n\tbody, headers, errMsg := h.executeWithAuthManagerFormats(ctx, req.EntryProtocol, req.ExitProtocol, req.Model, cloneBytes(req.Body), req.Alt, false, modelExecutionOptions{\n\t\tHeaders:                 req.Headers,\n\t\tQuery:                   req.Query,\n\t\tInternalSource:          true,\n\t\tSkipInterceptorPluginID: req.SkipInterceptorPluginID,\n\t\tSkipRouterPluginID:      req.SkipRouterPluginID,\n\t})\n\tif errMsg != nil {\n\t\treturn ModelExecutionResponse{}, errMsg\n\t}\n\treturn ModelExecutionResponse{\n\t\tStatusCode: http.StatusOK,\n\t\tHeaders:    cloneHeader(headers),\n\t\tBody:       cloneBytes(body),\n\t}, nil\n}\n","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/sdk/api/handlers/model_execution.go#L81-L117","documentation":"Programmer error in the plugin/host model API: ExecuteModel() only performs non-streaming internal model requests, so calling it with ModelExecutionRequest{Stream: true} is rejected immediately with a mode error before any dispatch. The streaming counterpart is ExecuteModelStream().","triggerScenarios":"A plugin or internal caller constructs a ModelExecutionRequest with Stream: true and passes it to BaseAPIHandler.ExecuteModel.","commonSituations":"Porting code between the streaming and non-streaming variants; copy-paste of a request struct that was originally built for the stream API.","solutions":["Set Stream: false in the request, or remove the field (zero value is false)","If you actually need chunks, call ExecuteModelStream with Stream: true instead"],"exampleFix":"// before\nresp, errMsg := h.ExecuteModel(ctx, ModelExecutionRequest{Model: name, Body: body, Stream: true})\n// after\nresp, errMsg := h.ExecuteModel(ctx, ModelExecutionRequest{Model: name, Body: body, Stream: false})","handlingStrategy":"validation","validationCode":"if req.Stream {\n    return nil, fmt.Errorf(\"use ExecuteModelStream for streaming; got Stream=true on ExecuteModel\")\n}\nresp, errMsg := h.ExecuteModel(ctx, req)","typeGuard":"func isNonStreamingExecution(req ModelExecutionRequest) bool {\n    return !req.Stream\n}","tryCatchPattern":"// Error is returned in-band via *interfaces.ErrorMessage, not a Go error:\nresp, errMsg := h.ExecuteModel(ctx, req)\nif errMsg != nil && strings.Contains(errMsg.Error(), \"requires Stream=false\") {\n    log.Error(\"programmer error: passed a streaming request to ExecuteModel\")\n}","preventionTips":["Construct ModelExecutionRequest next to the call site with the matching Stream value","Enforce the pairing in code review: ExecuteModel<->false, ExecuteModelStream<->true","Add unit tests asserting mode errors fire for mismatched Stream flags"],"tags":["api-misuse","sdk","plugin-api","validation"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}