{"record":{"id":"f0a02f047389af87","repo":"chenhg5/cc-connect","slug":"gemini-stt-marshal-request-w","errorCode":null,"errorMessage":"gemini stt: marshal request: %w","messagePattern":"gemini stt: marshal request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"core/speech.go","lineNumber":254,"sourceCode":"\t\t\t{\n\t\t\t\t\"parts\": []map[string]any{\n\t\t\t\t\t{\n\t\t\t\t\t\t\"inline_data\": map[string]any{\n\t\t\t\t\t\t\t\"mime_type\": mime,\n\t\t\t\t\t\t\t\"data\":      b64,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"text\": prompt,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tjsonData, err := json.Marshal(reqBody)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"gemini stt: marshal request: %w\", err)\n\t}\n\n\tapiURL := fmt.Sprintf(\"%s/models/%s:generateContent\", g.BaseURL, url.PathEscape(g.Model))\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(jsonData))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"gemini stt: create request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"x-goog-api-key\", g.APIKey)\n\n\tresp, err := g.Client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"gemini stt: request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/speech.go#L236-L272","documentation":"Thrown by GeminiSTT.Transcribe in core/speech.go when json.Marshal fails while serializing the Gemini generateContent request body. json.Marshal on a plain anonymous struct built from strings/bytes essentially never fails in practice, so this error indicates an extraordinary serialization failure (e.g. unsupported value introduced by future code changes).","triggerScenarios":"json.Marshal(reqBody) returns an error — practically only if reqBody ever contains a value that cannot be marshaled (channel, func, cyclic reference) after future modifications; not reachable with the current fixed struct.","commonSituations":"Essentially never hit by users of the current code; would surface only after a developer adds a field with an unmarshalable type to the Gemini request struct.","solutions":["If it occurs, inspect the wrapped json error naming the offending field/type.","Review recent changes to the reqBody struct in GeminiSTT.Transcribe for unmarshalable types (chan, func, cycles).","Replace unsupported fields with marshalable equivalents ([]byte, string, etc.)."],"exampleFix":"// before\nInlineData{MIMEType: \"audio/mp3\", Data: ch} // ch is a channel: unmarshalable\n// after\nInlineData{MIMEType: \"audio/mp3\", Data: audioBytes} // []byte, marshalable","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"text, err := stt.Transcribe(ctx, audio)\nif err != nil {\n    if strings.Contains(err.Error(), \"marshal request\") {\n        slog.Error(\"gemini stt: request serialization failed\", \"err\", err)\n        return \"\", err // genuine bug: fail fast\n    }\n    return err\n}","preventionTips":["Keep the request struct limited to marshalable types (string, []byte, ints, slices).","Add a unit test marshaling the request body to catch regressions early.","Do not inject dynamic values (channels, funcs) into the request payload."],"tags":["json","speech-to-text","gemini","serialization"],"backgroundTag":"json-marshal-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}