{"record":{"id":"7df0c14a65ad9a08","repo":"chenhg5/cc-connect","slug":"qwen-tts-api-error-s-s","errorCode":null,"errorMessage":"qwen tts API error %s: %s","messagePattern":"qwen tts API error (.+?): (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tts.go","lineNumber":173,"sourceCode":"\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts API %d: %s\", resp.StatusCode, body)\n\t}\n\n\tvar result struct {\n\t\tCode    string `json:\"code\"`\n\t\tMessage string `json:\"message\"`\n\t\tOutput  struct {\n\t\t\tAudio struct {\n\t\t\t\tURL string `json:\"url\"`\n\t\t\t} `json:\"audio\"`\n\t\t} `json:\"output\"`\n\t}\n\tif err := json.Unmarshal(body, &result); err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: parse response: %w\", err)\n\t}\n\tif result.Code != \"\" {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts API error %s: %s\", result.Code, result.Message)\n\t}\n\tif result.Output.Audio.URL == \"\" {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: empty audio URL in response\")\n\t}\n\n\t// Download WAV from temporary URL\n\taudioReq, err := http.NewRequestWithContext(ctx, http.MethodGet, result.Output.Audio.URL, nil)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: create download request: %w\", err)\n\t}\n\taudioResp, err := q.Client.Do(audioReq)\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"qwen tts: download audio: %w\", err)\n\t}\n\tdefer audioResp.Body.Close()\n\n\twavData, err := io.ReadAll(audioResp.Body)\n\tif err != nil {","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/tts.go#L155-L191","documentation":"The Qwen TTS API can return HTTP 200 with an application-level error encoded in the JSON envelope (non-empty \"code\" and \"message\"). Synthesize detects result.Code != \"\" and surfaces it as 'qwen tts API error <code>: <message>'. HTTP status alone is insufficient for this API.","triggerScenarios":"A 200 response whose JSON contains a non-empty top-level \"code\" field — e.g. invalid parameter values, model not entitled, text too long, content policy rejection.","commonSituations":"Input text exceeding the model's length limit; unsupported language_type value; model name unavailable to the account; content filtered by the provider despite successful HTTP handling.","solutions":["Read the code and message in the error and look them up in the Dashscope error-code docs.","Fix the input per the message: shorten text, correct language_type, use an entitled model.","Check account entitlement/quota for the chosen model in the provider console.","Surface the code/message to the end user in the messaging layer instead of a generic failure."],"exampleFix":"// before\ncode := result.Code // checked after unmarshal, surfaced only as error\n// after\nif result.Code != \"\" {\n    slog.Warn(\"qwen tts business error\", \"code\", result.Code, \"msg\", result.Message)\n    return nil, \"\", fmt.Errorf(\"qwen tts API error %s: %s\", result.Code, result.Message)\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight input checks\nif len([]rune(text)) > maxQwenInputChars {\n    return fmt.Errorf(\"text too long for Qwen TTS (limit ~%d chars)\", maxQwenInputChars)\n}\nif opts.LanguageType != \"\" && !supportedLanguageTypes[opts.LanguageType] {\n    return fmt.Errorf(\"unsupported language_type %q\", opts.LanguageType)\n}","typeGuard":"func isQwenBusinessError(err error) (code, msg string, ok bool) {\n    if err == nil { return \"\", \"\", false }\n    const p = \"qwen tts API error \"\n    if !strings.HasPrefix(err.Error(), p) { return \"\", \"\", false }\n    rest := strings.TrimPrefix(err.Error(), p)\n    parts := strings.SplitN(rest, \": \", 2)\n    return parts[0], strings.Join(parts[1:], \": \"), true\n}","tryCatchPattern":"_, _, err := q.Synthesize(ctx, text, opts)\nif code, msg, ok := isQwenBusinessError(err); ok {\n    reply(fmt.Sprintf(\"TTS failed (%s): %s\", code, msg))\n    return\n}","preventionTips":["Validate input length and language_type against provider limits before calling.","Surface the provider's code/message to users instead of a generic failure.","Keep a mapping of common Qwen error codes to user actions.","Watch for entitlement errors after changing model names."],"tags":["tts","qwen","api","error-response"],"backgroundTag":"upstream-api-error","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"}