SubtitleEdit/subtitleedit · error · Exception

DeepLXTranslate error: StatusCode={result.StatusCode} {resul

Error message

DeepLXTranslate error: StatusCode={result.StatusCode}
{resultContent}

What it means

Thrown by the DeepLX translator (a self-hosted reverse-engineering of DeepL, default http://localhost:1188) when the POST to /translate returns a non-success status after retries. The status code and body are surfaced. Unlike the official DeepL, DeepLX depends on a local service that scrapes DeepL's web endpoint.

Source

Thrown at src/libuilogic/AutoTranslate/DeepLXTranslate.cs:72

            HttpResponseMessage result = null!;
            var resultContent = string.Empty;
            for (var attempt = 0; attempt <= retryDelays.Length; attempt++)
            {
                var postContent = MakeContent(text, sourceLanguageCode, targetLanguageCode);
                result = await _httpClient.PostAsync("/translate", postContent, cancellationToken);
                resultContent = await result.Content.ReadAsStringAsync(cancellationToken);

                if (!DeepLTranslate.ShouldRetry(result, resultContent) || attempt == retryDelays.Length)
                {
                    break;
                }

                await Task.Delay(retryDelays[attempt], cancellationToken);
            }

            if (!result.IsSuccessStatusCode)
            {
                throw new Exception("DeepLXTranslate error: StatusCode=" + result.StatusCode + Environment.NewLine + resultContent);
            }

            try
            {
                var parser = new SeJsonParser();
                var alternatives = parser.GetArrayElementsByName(resultContent, "alternatives");
                var data = string.Empty;
                if (alternatives.Count > 0 && alternatives[0] != null)
                {
                    data = alternatives[0];
                }

                if (string.IsNullOrEmpty(data))
                {
                    var dataValues = parser.GetAllTagsByNameAsStrings(resultContent, "data");
                    if (dataValues.Count > 0)
                    {
                        data = dataValues[0];

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Confirm the DeepLX service is up: curl the configured URL + /translate with a sample payload.
  2. Verify Configuration.Settings.Tools.AutoTranslateDeepLXUrl matches where DeepLX actually listens (default http://localhost:1188).
  3. Restart DeepLX and check its own logs for upstream DeepL blocks.
  4. If running DeepLX remotely, ensure the host can reach it and the port is open.

Example fix

// before
if (!result.IsSuccessStatusCode)
{
    throw new Exception("DeepLXTranslate error: StatusCode=" + result.StatusCode + Environment.NewLine + resultContent);
}

// after - distinguish connectivity (502/503) from DeepLX-internal errors (500) to guide the user
if (!result.IsSuccessStatusCode)
{
    var hint = (int)result.StatusCode >= 500
        ? "DeepLX server error - is the DeepLX service running and reachable at " + _apiUrl + "?"
        : "DeepLX returned " + (int)result.StatusCode + " - check the request payload and DeepLX config.";
    throw new Exception("DeepLXTranslate error: " + hint + Environment.NewLine + "StatusCode=" + result.StatusCode + Environment.NewLine + resultContent);
}
Defensive patterns

Strategy: validation

Validate before calling

// Before translating, confirm the DeepLX service is reachable
var url = Configuration.Settings.Tools.AutoTranslateDeepLXUrl;
if (string.IsNullOrWhiteSpace(url))
    throw new InvalidOperationException("DeepLX URL is not configured.");
using var probe = new HttpClient { Timeout = TimeSpan.FromSeconds(3) };
try
{
    var resp = await probe.GetAsync(url.TrimEnd('/') + "/translate");
}
catch (Exception ex)
{
    throw new InvalidOperationException($"DeepLX service at {url} is not reachable: {ex.Message}");
}

Type guard

public static async Task<bool> IsDeepLXReachableAsync(string url)
{
    if (string.IsNullOrWhiteSpace(url)) return false;
    using var c = new HttpClient { Timeout = TimeSpan.FromSeconds(3) };
    try { await c.GetAsync(url.TrimEnd('/')); return true; } catch { return false; }
}

Try / catch

try
{
    return await deepLX.Translate(text, src, tgt, token);
}
catch (Exception ex) when (ex.Message.Contains("DeepLXTranslate error"))
{
    throw new InvalidOperationException($"DeepLX at {deepLXUrl} returned an error - confirm the service is running. Inner: {ex.Message}", ex);
}

Prevention

When it happens

Trigger: Translate() posts JSON {source_lang, target_lang, text} to the configured DeepLX URL /translate; ShouldRetry only handles 429/503, so any other non-success (404, 500, 502) lands here immediately. Most often the local DeepLX service is down, misconfigured, or blocked upstream.

Common situations: DeepLX docker/process not running on the configured port; wrong AutoTranslateDeepLXUrl in settings (still localhost when service is remote, or vice versa); DeepLX itself returning 500 because DeepL's web endpoint rate-limited or blocked the DeepLX IP; CORS/network egress blocked.

Related errors


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