{"record":{"id":"048a5111a36b0691","repo":"chenhg5/cc-connect","slug":"whisper-api-d-s","errorCode":null,"errorMessage":"whisper API %d: %s","messagePattern":"whisper API (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/speech.go","lineNumber":96,"sourceCode":"\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"create request: %w\", err)\n\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+w.APIKey)\n\treq.Header.Set(\"Content-Type\", writer.FormDataContentType())\n\n\tresp, err := w.Client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"whisper request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"read response: %w\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"whisper API %d: %s\", resp.StatusCode, string(body))\n\t}\n\n\t// response_format=text returns plain text; try to handle JSON fallback\n\ttext := strings.TrimSpace(string(body))\n\tif strings.HasPrefix(text, \"{\") {\n\t\tvar jr struct {\n\t\t\tText string `json:\"text\"`\n\t\t}\n\t\tif json.Unmarshal(body, &jr) == nil {\n\t\t\ttext = jr.Text\n\t\t}\n\t}\n\treturn text, nil\n}\n\n// QwenASR implements SpeechToText using the Qwen ASR model via DashScope's\n// OpenAI-compatible chat completions API. Unlike Whisper, audio is sent as a\n// base64 data URI inside the messages array.","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/speech.go#L78-L114","documentation":"The Whisper API returned a non-200 status; Transcribe surfaces the status code and the raw response body. This is the server-side error path: auth failures (401), bad model name (404/400), quota/billing (429), or server errors (5xx).","triggerScenarios":"Transcribe called with an invalid or expired API key (401), a Model not available on the endpoint (404/400), exceeded rate limits (429), invalid audio format (400), or provider outage (500/503).","commonSituations":"Missing/typo'd OPENAI_API_KEY or provider key in config; using whisper-1 against Groq which requires 'whisper-large-v3'; billing/quota exhausted; sending an unsupported audio extension to the endpoint.","solutions":["Read the body in the error message — providers include a JSON reason (e.g. invalid_api_key, model_not_found)","For 401, verify the API key is correct, active, and has audio API access","For 404/400 model errors, set Model to one supported by the endpoint (e.g. whisper-large-v3 for Groq)","For 429, add backoff/retry and check quota/billing","For 5xx, retry later or check the provider status page"],"exampleFix":"// before (Groq endpoint with OpenAI default model)\nNewOpenAIWhisper(key, \"https://api.groq.com/openai/v1\", \"\") // defaults to whisper-1 -> 404\n// after\nNewOpenAIWhisper(key, \"https://api.groq.com/openai/v1\", \"whisper-large-v3\")","handlingStrategy":"try-catch","validationCode":"if cfg.WhisperAPIKey == \"\" {\n    return fmt.Errorf(\"missing whisper api_key in config\")\n}\nif !slices.Contains(supportedModels, cfg.WhisperModel) {\n    return fmt.Errorf(\"model %q not supported by endpoint\", cfg.WhisperModel)\n}","typeGuard":null,"tryCatchPattern":"text, err := stt.Transcribe(ctx, audio, format, lang)\nif err != nil {\n    var apiErr *HTTPStatusError // or parse 'whisper API %d:' prefix\n    if strings.Contains(err.Error(), \"whisper API 401\") {\n        slog.Error(\"whisper auth failed: check api_key\")\n    } else if strings.Contains(err.Error(), \"whisper API 429\") {\n        // back off and retry\n    } else {\n        slog.Error(\"whisper API error\", \"err\", err)\n    }\n}","preventionTips":["Verify the API key works with the audio endpoint before deploying","Match the model name to the provider (whisper-1 for OpenAI, whisper-large-v3 for Groq)","Monitor quota/billing to avoid surprise 429s","Log the response body included in the error — providers explain the exact cause","Add exponential backoff for 429/5xx responses"],"tags":["http","api","whisper","authentication"],"backgroundTag":"http-error-response","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"}