{"record":{"id":"89a5c83d6bf96321","repo":"chenhg5/cc-connect","slug":"minimax-tts-api-d-s","errorCode":null,"errorMessage":"minimax tts API %d: %s","messagePattern":"minimax tts API (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tts.go","lineNumber":349,"sourceCode":"\t}\n\n\turl := strings.TrimRight(m.BaseURL, \"/\") + \"/v1/t2a_v2\"\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(jsonData))\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"minimax tts: create request: %w\", err)\n\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+m.APIKey)\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := m.Client.Do(req)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"minimax tts: request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := io.ReadAll(resp.Body)\n\t\treturn nil, \"\", fmt.Errorf(\"minimax tts API %d: %s\", resp.StatusCode, body)\n\t}\n\n\t// Parse SSE stream: each line is \"data: {...}\" with hex-encoded audio chunks.\n\tvar audioBuf bytes.Buffer\n\tscanner := bufio.NewScanner(resp.Body)\n\tscanner.Buffer(make([]byte, 0, 1024*1024), 10*1024*1024)\n\tfor scanner.Scan() {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, \"\", ctx.Err()\n\t\tdefault:\n\t\t}\n\t\tline := scanner.Text()\n\t\tif !strings.HasPrefix(line, \"data:\") {\n\t\t\tcontinue\n\t\t}\n\t\tdata := strings.TrimSpace(strings.TrimPrefix(line, \"data:\"))\n\t\tif data == \"\" {","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/tts.go#L331-L367","documentation":"This error is returned when the MiniMax TTS endpoint replies with a non-200 HTTP status. It includes the status code and up to the full response body so the caller can see the server's reason (auth failure, bad model, rate limit, etc.). Unlike the business-error path (error 893), this fires before any SSE parsing, on transport-level rejection.","triggerScenarios":"MiniMax API returns 401 (invalid/expired API key), 400 (malformed request body), 429 (rate limited), or 5xx; a proxy or gateway returns an HTML error page with a non-200 status.","commonSituations":"Expired or wrong minimax API key in config.toml; account out of quota; wrong base_url hitting a non-MiniMax service; 502/503 from a gateway during MiniMax incidents.","solutions":["Read the body embedded in the error: 401/403 → fix the API key in config.toml; 429 → back off and retry; 5xx → retry later or check MiniMax status.","Regenerate the MiniMax API key and update config.toml if authentication failed.","Confirm base_url points to the correct MiniMax host for your region.","Implement retry with exponential backoff for 429 and 5xx responses."],"exampleFix":"// before\nclient.Do(req) // 401 body: {\"base_resp\":{\"status_code\":1004,\"status_msg\":\"invalid api key\"}}\n// after\n// fix config.toml: api_key = \"sk-...\" with a fresh key from the MiniMax console","handlingStrategy":"try-catch","validationCode":"if cfg.APIKey == \"\" { return errors.New(\"minimax api_key missing\") }","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var apiErr *HTTPStatusError // or parse \"minimax tts API %d: %s\"\n    if strings.Contains(err.Error(), \"minimax tts API 401\") {\n        // rotate API key\n    } else if strings.Contains(err.Error(), \"minimax tts API 429\") {\n        // backoff and retry\n    }\n}","preventionTips":["Keep MiniMax API keys fresh and monitor account quota/balance","Validate api_key is present at config load","Distinguish 4xx from 5xx before deciding to retry","Subscribe to provider status for outage awareness"],"tags":["go","http","api","tts","minimax"],"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-14T05:17:10.506Z"}