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
- Confirm the DeepLX service is up: curl the configured URL + /translate with a sample payload.
- Verify Configuration.Settings.Tools.AutoTranslateDeepLXUrl matches where DeepLX actually listens (default http://localhost:1188).
- Restart DeepLX and check its own logs for upstream DeepL blocks.
- 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
- Run DeepLX as a managed service/daemon so it auto-restarts.
- Health-check the DeepLX URL on translator selection, not just at translate time.
- Keep DeepLX on the version this client's parser supports.
- Log the configured URL in failures so operators know which instance was hit.
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
- {StaticName} returned an unexpected response: {responseStrin
- CrispASR exited with code {process.ExitCode}: {Error}
- Forbidden! {resultContent}
- DeepL failed with status code {(int)result.StatusCode} ({res
- DeepLXTranslate gave empty alternatives: StatusCode={result.
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/76d5669cc1a6abd4.
Report an issue: GitHub.