{"record":{"id":"d771a04cd5d6b742","repo":"SubtitleEdit/subtitleedit","slug":"deeplxtranslate-gave-empty-alternatives-statuscod","errorCode":null,"errorMessage":"DeepLXTranslate gave empty alternatives: StatusCode={result.StatusCode}\n{resultContent}","messagePattern":"DeepLXTranslate gave empty alternatives: StatusCode=(.+?)\n(.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/libuilogic/AutoTranslate/DeepLXTranslate.cs","lineNumber":102,"sourceCode":"\n                if (string.IsNullOrEmpty(data))\n                {\n                    var dataValues = parser.GetAllTagsByNameAsStrings(resultContent, \"data\");\n                    if (dataValues.Count > 0)\n                    {\n                        data = dataValues[0];\n                    }\n                }\n\n                if (!string.IsNullOrEmpty(data))\n                {\n                    var resultText = Json.DecodeJsonText(data);\n                    var resultTextWithFixedNewLines = ChatGptTranslate.FixNewLines(resultText);\n                    return resultTextWithFixedNewLines.Trim();\n                }\n\n                SeLogger.Error(\"DeepLXTranslate.Translate: \" + resultContent);\n                throw new Exception(\"DeepLXTranslate gave empty alternatives: StatusCode=\" + result.StatusCode + Environment.NewLine + resultContent);\n            }\n            catch (Exception ex)\n            {\n                SeLogger.Error(ex, \"DeepLXTranslate.Translate: \" + ex.Message + Environment.NewLine + resultContent);\n                throw;\n            }\n        }\n\n        private static StringContent MakeContent(string text, string sourceLanguageCode, string targetLanguageCode)\n        {\n            var input = \"{ \\\"source_lang\\\": \\\"\" + sourceLanguageCode + \"\\\", \\\"target_lang\\\": \\\"\" + targetLanguageCode + \"\\\", \\\"text\\\": \\\"\" + Json.EncodeJsonText(text.Trim(), \"\\\\n\") + \"\\\" }\";\n            var content = new StringContent(input, Encoding.UTF8);\n            return content;\n        }\n\n        public void Dispose()\n        {\n            _httpClient?.Dispose();","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/libuilogic/AutoTranslate/DeepLXTranslate.cs#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Log/capture the raw resultContent to see what DeepLX actually returned.","Pin the DeepLX version to one matching this client's parser, or update SubtitleEdit.","Test the same language pair directly against DeepLX with curl to isolate the schema issue.","Try a well-supported language pair (e.g. en -> de) to rule out pair-specific emptiness."],"exampleFix":"// before\nSeLogger.Error(\"DeepLXTranslate.Translate: \" + resultContent);\nthrow new Exception(\"DeepLXTranslate gave empty alternatives: StatusCode=\" + result.StatusCode + Environment.NewLine + resultContent);\n\n// after - keep the raw body for diagnosis and hint at version mismatch\nSeLogger.Error(\"DeepLXTranslate.Translate: empty result body was: \" + resultContent);\nthrow new Exception(\"DeepLXTranslate returned no translatable text (possible version/schema mismatch with DeepLX). StatusCode=\" + result.StatusCode + Environment.NewLine + resultContent);","handlingStrategy":"fallback","validationCode":"// Before trusting the DeepLX response, sanity-check it parses as JSON with expected keys\ntry\n{\n    var jo = Newtonsoft.Json.Linq.JObject.Parse(resultContent);\n    if (jo[\"alternatives\"] == null && jo[\"data\"] == null)\n        throw new InvalidOperationException(\"DeepLX response has no 'alternatives' or 'data' key - possible version mismatch.\");\n}\ncatch (Newtonsoft.Json.JsonReaderException)\n{\n    throw new InvalidOperationException(\"DeepLX did not return valid JSON.\");\n}","typeGuard":"public static bool HasDeepLXResultField(string body)\n    => body.Contains(\"\\\"alternatives\\\"\") || body.Contains(\"\\\"data\\\"\");","tryCatchPattern":"try\n{\n    return await deepLX.Translate(text, src, tgt, token);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"empty alternatives\"))\n{\n    // Fall back to another translator or surface a version-mismatch hint\n    throw new InvalidOperationException(\"DeepLX returned no text - its response schema may differ from the expected version.\", ex);\n}","preventionTips":["Pin the DeepLX version; test after upgrades since the schema can change.","Pre-test an en->de translation to confirm the response shape before batch use.","Capture raw response bodies during development to detect schema drift early.","Offer a fallback translator so a DeepLX schema change does not halt a run."],"tags":["parsing","schema","translation","deeplx"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}