SubtitleEdit/subtitleedit · error · InvalidOperationException

DashScope task succeeded but returned no transcription_url.

Error message

DashScope task succeeded but returned no transcription_url. Response: {json}

What it means

Thrown when the task status is SUCCEEDED but neither Output.Result.TranscriptionUrl nor Output.Results[0].TranscriptionUrl is present. The transcription completed but DashScope didn't return a URL to download the result JSON, making the output inaccessible.

Source

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

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _settings.ApiKey);

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

            var output = JsonSerializer.Deserialize<DashScopeTaskResponse>(json, options)?.Output;
            var status = output?.TaskStatus ?? "UNKNOWN";
            switch (status.ToUpperInvariant())
            {
                case "SUCCEEDED":
                    var transcriptionUrl = output?.Result?.TranscriptionUrl
                        ?? (output?.Results != null && output.Results.Count > 0 ? output.Results[0].TranscriptionUrl : null);
                    if (string.IsNullOrEmpty(transcriptionUrl))
                    {
                        throw new InvalidOperationException($"DashScope task succeeded but returned no transcription_url. Response: {json}");
                    }
                    return transcriptionUrl;

                case "FAILED":
                case "UNKNOWN":
                    throw new InvalidOperationException($"DashScope transcription task {status}. Response: {json}");

                default: // QUEUED, PENDING, PROCESSING
                    await Task.Delay(TimeSpan.FromSeconds(3), ct);
                    break;
            }
        }
    }

    /// <summary>
    /// Serialize the async submit body. <c>enable_words</c> adds word-level
    /// timings; a fixed language is sent only when the user set one.
    /// </summary>

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Inspect the raw json in the error to see what fields the SUCCEEDED response actually contains.
  2. If transcription_url moved, update DashScopeTaskResponse's Result/Results DTOs to match the new schema.
  3. Re-run the transcription — if OSS expiry is the cause, the URL will be fresh on a new task.
  4. Check DashScope release notes for API response format changes.
  5. Report to DashScope support if the response genuinely lacks the URL on a confirmed SUCCEEDED task.
Defensive patterns

Strategy: try-catch

Validate before calling

// Defensive JSON inspection before accessing transcription_url
using var doc = JsonDocument.Parse(json);
var root = doc.RootElement;
string? url = null;
if (root.TryGetProperty("output", out var outEl))
{
    if (outEl.TryGetProperty("result", out var resEl) && resEl.TryGetProperty("transcription_url", out var u1))
        url = u1.GetString();
    else if (outEl.TryGetProperty("results", out var resArr) && resArr.GetArrayLength() > 0
             && resArr[0].TryGetProperty("transcription_url", out var u2))
        url = u2.GetString();
}
if (string.IsNullOrEmpty(url))
    throw new InvalidOperationException("SUCCEEDED task missing transcription_url.");

Try / catch

try { return await PollTaskAsync(taskId, ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("no transcription_url"))
{ /* log JSON, check if URL field moved, re-run transcription if expired */ }

Prevention

When it happens

Trigger: The response JSON for a SUCCEEDED task lacks the transcription_url field in both Result and Results; the Results array is empty; the field was renamed in a DashScope API update; the result URL was redacted due to OSS expiry.

Common situations: DashScope API schema change renamed or moved transcription_url; the task succeeded but the result file expired on OSS before the poll fetched it; the account's OSS retention policy deleted the output; a partial success where transcription ran but URL generation failed server-side.

Related errors


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