SubtitleEdit/subtitleedit · error · Exception

DeepLXTranslate gave empty alternatives: StatusCode={result.

Error message

DeepLXTranslate gave empty alternatives: StatusCode={result.StatusCode}
{resultContent}

What it means

Thrown by DeepLXTranslate when the HTTP response was 2xx (success) but the JSON body contains neither an 'alternatives' array element nor a 'data' field usable as the translated text. Indicates a schema/protocol drift between this client and the DeepLX version, or an empty result DeepLX returned without erroring.

Source

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

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

                if (!string.IsNullOrEmpty(data))
                {
                    var resultText = Json.DecodeJsonText(data);
                    var resultTextWithFixedNewLines = ChatGptTranslate.FixNewLines(resultText);
                    return resultTextWithFixedNewLines.Trim();
                }

                SeLogger.Error("DeepLXTranslate.Translate: " + resultContent);
                throw new Exception("DeepLXTranslate gave empty alternatives: StatusCode=" + result.StatusCode + Environment.NewLine + resultContent);
            }
            catch (Exception ex)
            {
                SeLogger.Error(ex, "DeepLXTranslate.Translate: " + ex.Message + Environment.NewLine + resultContent);
                throw;
            }
        }

        private static StringContent MakeContent(string text, string sourceLanguageCode, string targetLanguageCode)
        {
            var input = "{ \"source_lang\": \"" + sourceLanguageCode + "\", \"target_lang\": \"" + targetLanguageCode + "\", \"text\": \"" + Json.EncodeJsonText(text.Trim(), "\\n") + "\" }";
            var content = new StringContent(input, Encoding.UTF8);
            return content;
        }

        public void Dispose()
        {
            _httpClient?.Dispose();

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Log/capture the raw resultContent to see what DeepLX actually returned.
  2. Pin the DeepLX version to one matching this client's parser, or update SubtitleEdit.
  3. Test the same language pair directly against DeepLX with curl to isolate the schema issue.
  4. Try a well-supported language pair (e.g. en -> de) to rule out pair-specific emptiness.

Example fix

// before
SeLogger.Error("DeepLXTranslate.Translate: " + resultContent);
throw new Exception("DeepLXTranslate gave empty alternatives: StatusCode=" + result.StatusCode + Environment.NewLine + resultContent);

// after - keep the raw body for diagnosis and hint at version mismatch
SeLogger.Error("DeepLXTranslate.Translate: empty result body was: " + resultContent);
throw new Exception("DeepLXTranslate returned no translatable text (possible version/schema mismatch with DeepLX). StatusCode=" + result.StatusCode + Environment.NewLine + resultContent);
Defensive patterns

Strategy: fallback

Validate before calling

// Before trusting the DeepLX response, sanity-check it parses as JSON with expected keys
try
{
    var jo = Newtonsoft.Json.Linq.JObject.Parse(resultContent);
    if (jo["alternatives"] == null && jo["data"] == null)
        throw new InvalidOperationException("DeepLX response has no 'alternatives' or 'data' key - possible version mismatch.");
}
catch (Newtonsoft.Json.JsonReaderException)
{
    throw new InvalidOperationException("DeepLX did not return valid JSON.");
}

Type guard

public static bool HasDeepLXResultField(string body)
    => body.Contains("\"alternatives\"") || body.Contains("\"data\"");

Try / catch

try
{
    return await deepLX.Translate(text, src, tgt, token);
}
catch (Exception ex) when (ex.Message.Contains("empty alternatives"))
{
    // Fall back to another translator or surface a version-mismatch hint
    throw new InvalidOperationException("DeepLX returned no text - its response schema may differ from the expected version.", ex);
}

Prevention

When it happens

Trigger: Translate() parses resultContent with SeJsonParser looking for 'alternatives' (GetArrayElementsByName) then falls back to 'data' (GetAllTagsByNameAsStrings); both come back empty/null, so execution reaches the throw at DeepLXTranslate.cs:102. Happens after a DeepLX version upgrade that changed its response schema, or when DeepLX returns an empty translation for unsupported language pairs.

Common situations: DeepLX upgraded to a version with a new response format; requesting a language pair DeepL/DeepLX does not support; DeepLX returned an empty alternatives list silently; mismatched DeepLX fork (the code targets github.com/OwO-Network/DeepLX).

Related errors


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