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.

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.

Appendix: 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)