{"record":{"id":"e71e53ee73c09a8d","repo":"micro/go-micro","slug":"failed-to-marshal-stream-request-w-e71e53","errorCode":null,"errorMessage":"failed to marshal stream request: %w","messagePattern":"failed to marshal stream request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/ollama/ollama.go","lineNumber":333,"sourceCode":"\t}\n\treturn response, raw, nil\n}\n\nfunc (p *Provider) streamOpenAI(ctx context.Context, req *ai.Request) (ai.Stream, error) {\n\tmessages := buildOpenAIMessages(req)\n\tapiReq := map[string]any{\n\t\t\"model\":          p.opts.Model,\n\t\t\"messages\":       messages,\n\t\t\"stream\":         true,\n\t\t\"stream_options\": map[string]any{\"include_usage\": true},\n\t}\n\tif p.opts.MaxTokens > 0 {\n\t\tapiReq[\"max_tokens\"] = p.opts.MaxTokens\n\t}\n\n\treqBody, err := json.Marshal(apiReq)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal stream request: %w\", err)\n\t}\n\n\tapiURL := strings.TrimRight(p.opts.BaseURL, \"/\") + p.streamPath()\n\thttpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create stream request: %w\", err)\n\t}\n\thttpReq.Header.Set(\"Content-Type\", \"application/json\")\n\thttpReq.Header.Set(\"Accept\", \"text/event-stream\")\n\tif p.opts.APIKey != \"\" {\n\t\thttpReq.Header.Set(\"Authorization\", \"Bearer \"+p.opts.APIKey)\n\t}\n\n\thttpResp, err := http.DefaultClient.Do(httpReq)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"stream API request failed: %w\", err)\n\t}\n\tif httpResp.StatusCode != http.StatusOK {","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/ollama/ollama.go#L315-L351","documentation":"Wraps json.Marshal failure when encoding the streaming chat request in the Ollama provider's streamOpenAI (called from Stream). Like the non-streaming variant, it indicates the apiReq map contains values that cannot be serialized to JSON.","triggerScenarios":"json.Marshal(apiReq) fails in streamOpenAI (called from Stream) — the request map includes non-JSON-serializable values: channels, funcs, cyclic references, or NaN/Inf numbers in options like temperature/top_p/max_tokens.","commonSituations":"Caller-supplied tools or options with unsupported types; NaN/Inf computed sampling parameters; cyclic metadata attached to the request.","solutions":["Audit the values passed into Stream options for non-serializable types","Replace NaN/Inf floats in temperature/top_p with valid numbers or omit them","Log the apiReq keys/types on failure to find the offending entry","Use a typed request struct instead of map[string]any for compile-time safety"],"exampleFix":"// before\nreqBody, err := json.Marshal(apiReq)\nif err != nil {\n    return nil, fmt.Errorf(\"failed to marshal stream request: %w\", err)\n}\n// after\nreqBody, err := json.Marshal(apiReq)\nif err != nil {\n    return nil, fmt.Errorf(\"failed to marshal stream request: %w: keys=%v\", err, mapKeys(apiReq))\n}","handlingStrategy":"validation","validationCode":"if math.IsNaN(opts.Temperature) || math.IsInf(opts.Temperature, 0) {\n    return fmt.Errorf(\"temperature must be finite\")\n}\nif err := json.Marshal(opts); err != nil {\n    return fmt.Errorf(\"stream options not serializable: %w\", err)\n}","typeGuard":"func isJSONSerializable(v any) bool {\n    _, err := json.Marshal(v)\n    return err == nil\n}","tryCatchPattern":"stream, err := provider.Stream(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to marshal stream request\") {\n        // audit apiReq fields for channels/funcs/cycles/NaN\n    }\n    return err\n}","preventionTips":["Pass only JSON-compatible values into stream options","Guard sampling floats against NaN/Inf","Avoid func/cyclic fields in request metadata","Unit-test Stream with realistic option sets"],"tags":["json","marshalling","streaming","ollama"],"backgroundTag":"json-marshal-failed","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}