SubtitleEdit/subtitleedit · error · HttpRequestException

DashScope async submit failed

Error message

DashScope async submit failed ({(int)response.StatusCode}). Response: {json}

What it means

Thrown when the POST to DashScope's async transcription submit endpoint (/api/v1/services/audio/asr/transcription) returns a non-success HTTP status. This is the step that creates the transcription job using the oss:// URL from the upload. The request includes X-DashScope-Async and X-DashScope-OssResourceResolve headers.

Solutions

  1. Examine the json response body in the error for DashScope's specific error code and message.
  2. Verify the model name in _settings.Model is valid and available (default: 'qwen3-asr-flash-filetrans').
  3. If the submit happens long after upload, the oss:// URL may have expired — reduce processing time or re-upload.
  4. Check for rate limiting (429) and implement backoff if submitting many files.
  5. Validate the language parameter format matches DashScope's expectations.
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the oss URL format before submitting
if (string.IsNullOrWhiteSpace(ossUrl) || !ossUrl.StartsWith("oss://"))
    throw new InvalidOperationException($"Invalid OSS URL for submission: {ossUrl}");

Try / catch

try { var taskId = await SubmitTaskAsync(ossUrl, language, ct); }
catch (HttpRequestException ex) when (ex.Message.Contains("async submit failed"))
{
    var code = ExtractStatusCode(ex.Message);
    if (code == 429) /* rate limited, backoff and retry */;
    else if (code == 400) /* check model/language parameters in body */;
}

Prevention

When it happens

Trigger: The API key lacks ASR permissions; the oss:// URL is malformed or expired; the request body (BuildSubmitBody) has invalid parameters (bad model, unsupported language, invalid parameter combination); the DashScope service is temporarily unavailable.

Common situations: The ASR model specified in settings is deprecated or not available in the region; the oss:// URL expired because too much time passed between upload and submit; the language code format is wrong; the request body JSON has an unexpected field; rate limiting.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/4658f7d748cc92ff. Report an issue: GitHub.

Appendix: source

Thrown at src/ui/Features/Video/SpeechToText/DashScope/DashScopeSttService.cs:179

    private async Task<string> SubmitTaskAsync(string ossUrl, string? language, CancellationToken ct)
    {
        var body = BuildSubmitBody(_settings, ossUrl, language);
        using var content = new StringContent(body, Encoding.UTF8, "application/json");
        using var request = new HttpRequestMessage(HttpMethod.Post, BaseUrl + TranscriptionPath)
        {
            Content = content,
        };
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _settings.ApiKey);
        request.Headers.TryAddWithoutValidation("X-DashScope-Async", "enable");
        request.Headers.TryAddWithoutValidation("X-DashScope-OssResourceResolve", "enable");

        using var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, ct);
        var json = await response.Content.ReadAsStringAsync(ct);
        if (!response.IsSuccessStatusCode)
        {
            _settings.Logger?.Invoke($"DashScope async submit failed ({(int)response.StatusCode}): {json}");
            throw new HttpRequestException($"DashScope async submit failed ({(int)response.StatusCode}). Response: {json}");
        }

        var taskId = JsonSerializer.Deserialize<DashScopeTaskResponse>(json,
            new JsonSerializerOptions { PropertyNameCaseInsensitive = true })?.Output?.TaskId;
        if (string.IsNullOrEmpty(taskId))
        {
            throw new InvalidOperationException($"DashScope async submit returned no task_id. Response: {json}");
        }

        return taskId;
    }

    private async Task<string> PollTaskAsync(string taskId, CancellationToken ct)
    {
        var url = BaseUrl + TasksPath + Uri.EscapeDataString(taskId);
        var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };

        while (true)

View on GitHub (pinned to 17a9f07487)