{"record":{"id":"d006e064fc59a2a3","repo":"router-for-me/CLIProxyAPI","slug":"executemodelstream-requires-stream-true","errorCode":null,"errorMessage":"ExecuteModelStream requires Stream=true","messagePattern":"ExecuteModelStream requires Stream=true","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"sdk/api/handlers/model_execution.go","lineNumber":124,"sourceCode":"\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\n// ExecuteModelStream executes an internal 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) ExecuteModelStream(ctx context.Context, req ModelExecutionRequest) (ModelExecutionStream, *interfaces.ErrorMessage) {\n\tif !req.Stream {\n\t\treturn ModelExecutionStream{}, modelExecutionModeError(\"ExecuteModelStream requires Stream=true\")\n\t}\n\tdataChan, headers, errChan := h.executeStreamWithAuthManagerFormats(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\tchunks, errMsg := prepareModelExecutionStream(ctx, dataChan, errChan)\n\tif errMsg != nil {\n\t\treturn ModelExecutionStream{}, errMsg\n\t}\n\treturn ModelExecutionStream{\n\t\tStatusCode: http.StatusOK,\n\t\tHeaders:    cloneHeader(headers),\n\t\tChunks:     chunks,\n\t}, nil\n}","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/sdk/api/handlers/model_execution.go#L106-L142","documentation":"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().","triggerScenarios":"A plugin builds a ModelExecutionRequest without setting Stream (defaults false) and passes it to BaseAPIHandler.ExecuteModelStream.","commonSituations":"Forgetting to set Stream: true when constructing the request for the streaming API — the most common variant since false is the zero value.","solutions":["Set Stream: true in the request passed to ExecuteModelStream","If you want a single buffered response, call ExecuteModel instead"],"exampleFix":"// before\nstream, errMsg := h.ExecuteModelStream(ctx, ModelExecutionRequest{Model: name, Body: body})\n// after\nstream, errMsg := h.ExecuteModelStream(ctx, ModelExecutionRequest{Model: name, Body: body, Stream: true})","handlingStrategy":"validation","validationCode":"if !req.Stream {\n    return nil, fmt.Errorf(\"use ExecuteModel for buffered responses; got Stream=false on ExecuteModelStream\")\n}\nstream, errMsg := h.ExecuteModelStream(ctx, req)","typeGuard":"func isStreamingExecution(req ModelExecutionRequest) bool {\n    return req.Stream\n}","tryCatchPattern":"stream, errMsg := h.ExecuteModelStream(ctx, req)\nif errMsg != nil && strings.Contains(errMsg.Error(), \"requires Stream=true\") {\n    log.Error(\"programmer error: Stream flag not set for the streaming API\")\n}","preventionTips":["Remember Stream defaults to false — always set it explicitly for streaming calls","Centralize request construction in one helper per mode to avoid flag drift"],"tags":["api-misuse","sdk","plugin-api","validation","streaming"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}