Live Transcription Translation Issue: "Cannot support translating German to de"

Hey there,

I am experiencing an issue with Live Transcription and Translation (LTT) when using the Zoom Video SDK for Web in conjunction with a React Native Video SDK client. When attempting to set the translation language to the same language as the speaking language (which the documentation states is a “common configuration”), we receive error 7305: INVALID_OPERATION - Cannot support translating German to de.

Additionally, all caption payloads received have language: 400 (NoTranslation) regardless of the language settings configured on either client.

Environment

  • Web Client: @zoom/videosdk (Web Video SDK)
  • Mobile Client: @zoom/react-native-videosdk (React Native Video SDK)
  • Platform: Windows 10, Next.js 15 (Web), React Native + Expo (Mobile)

Expected Behavior

Per the official documentation:

“You can also set the speaking language and translation language to be the same (this is a common configuration).”

I expect to be able to:

  1. Set both setSpeakingLanguage('de') and setTranslationLanguage('de') on the Web client
  2. Receive translated captions from speakers using other languages (e.g., English speaker → German translation)
  3. Receive captions with the appropriate language code (e.g., 3 for German) when translation is enabled

Actual Behavior

  1. setSpeakingLanguage('de') succeeds
  2. setTranslationLanguage('de') fails with error:
    {type: 'INVALID_OPERATION', reason: 'Cannot support translating German to de', errorCode: 7305}
    
  3. All received caption payloads have language: 400 (NoTranslation), even when the React Native client successfully sets its language to English

Reproduction Steps

Setup

  • User A (Web): Using Zoom Video SDK for Web, locale set to German
  • User B (React Native): Using Zoom React Native Video SDK, language set to English

Steps

  1. User B (React Native) joins the session first and sets:

    • Speaking language: English (languageId: 0)
    • Translation language: English (languageId: 0)
    • Enables enableReceiveSpokenLanguageContent(true)
  2. User A (Web) joins the session and:

    • Starts live transcription
    • Sets speaking language to German (‘de’) - succeeds
    • Attempts to set translation language to German (‘de’) - fails with error 7305
  3. User B speaks in English

  4. User A receives caption payloads with language: 400 (NoTranslation) instead of translated German text

Code Snippets

Web Client (TypeScript/Next.js)

Initialization on session join:

// Start live transcription in the background
const captionsClient = client.getLiveTranscriptionClient();
if (captionsClient) {
  await captionsClient.startLiveTranscription();
  const userSpeakingLang = 'de'; // User's locale is German
  await captionsClient.setSpeakingLanguage(userSpeakingLang as LiveTranscriptionLanguage);
  await captionsClient.setTranslationLanguage(undefined); // Initially no translation
}

Toggle captions function:

const toggleCaptions = useCallback(async (): Promise<void> => {
  if (!client || !isJoined || !lttClient) return;

  try {
    if (isCaptionsEnabled) {
      setIsCaptionsEnabled(false);
      setCaptions([]);
      await lttClient.setTranslationLanguage(undefined);
    } else {
      const lttLang = 'de'; // User's locale

      // Debug logging
      const currentSpeaking = lttClient.getCurrentTranscriptionLanguage();
      const currentTranslation = lttClient.getCurrentTranslationLanguage();
      console.log('[DEBUG] Current speaking:', currentSpeaking, 'Current translation:', currentTranslation);

      // Set both speaking and translation to the same language (per docs)
      await lttClient.setSpeakingLanguage(lttLang as LiveTranscriptionLanguage);
      console.log('[DEBUG] setSpeakingLanguage succeeded');
      
      // THIS FAILS with error 7305
      await lttClient.setTranslationLanguage(lttLang as LiveTranscriptionLanguage);
      console.log('[DEBUG] setTranslationLanguage succeeded');

      setIsCaptionsEnabled(true);
    }
  } catch (err) {
    console.error('Toggle captions error:', err);
  }
}, [client, isJoined, isCaptionsEnabled, lttClient]);

Caption message handler:

client.on('caption-message', (payload: LiveTranscriptionMessage) => {
  console.log('Caption payload:', payload);
  // payload.language is always 400 (NoTranslation)
});

React Native Client

Initialization on session join:

// Auto-set transcription languages based on user's account language
const spokenLangs = await zoom.liveTranscriptionHelper.getAvailableSpokenLanguages();
const translationLangs = await zoom.liveTranscriptionHelper.getAvailableTranslationLanguages();

// Find English language (languageId: 0)
const matchingSpokenLang = spokenLangs.find(lang => 
  lang.languageName.toLowerCase().includes('english')
);
if (matchingSpokenLang) {
  const res1 = await zoom.liveTranscriptionHelper.setSpokenLanguage(matchingSpokenLang.languageId);
  console.log('setSpokenLanguage result', res1); // ZoomVideoSDKError_Success
}

const matchingTranslationLang = translationLangs.find(lang => 
  lang.languageName.toLowerCase().includes('english')
);
if (matchingTranslationLang) {
  const res2 = await zoom.liveTranscriptionHelper.setTranslationLanguage(matchingTranslationLang.languageId);
  console.log('setTranslationLanguage result', res2); // ZoomVideoSDKError_Success
}

// Enable receiving both original and translated speech text
const enableResult = await zoom.liveTranscriptionHelper.enableReceiveSpokenLanguageContent(true);
console.log('enableReceiveSpokenLanguageContent result', enableResult); // ZoomVideoSDKError_Success

Message listeners:

// Original language message received
zoom.addListener(EventType.onOriginalLanguageMsgReceived, ({messageInfo}) => {
  console.log('originalLanguageMsgListener', messageInfo);
});

// Translated message received
zoom.addListener(EventType.onLiveTranscriptionMsgInfoReceived, ({messageInfo}) => {
  console.log('liveTranscriptionMsgListener', messageInfo);
});

Console Logs

Web Client Logs

[DEBUG] Before toggle - Current speaking: {code: 'de', name: 'German'} Current translation: null
[DEBUG] Will set both to: de
[DEBUG] setSpeakingLanguage succeeded
Failed to set transcription languages: de , error: {type: 'INVALID_OPERATION', reason: 'Cannot support translating German to de', errorCode: 7305}

// Caption payloads received after React Native user speaks English:
Caption payload: {text: 'Hello.', language: 400, displayName: 'Noah Shcenk', done: false}
Caption payload: {text: 'Hello, how are you?', language: 400, displayName: 'Noah Shcenk', done: false}
Caption payload: {text: 'Hello, how are you?', language: 400, displayName: 'Noah Shcenk', done: true}

React Native Client Logs

matching Spoken Language {"languageId": 0, "languageName": "English"}
setSpokenLanguage result ZoomVideoSDKError_Success
matching Translation Language {"languageId": 0, "languageName": "English"}
setTranslationLanguage result ZoomVideoSDKError_Success
enableReceiveSpokenLanguageContent result ZoomVideoSDKError_Success
liveTranscriptionStatusListener ZoomVideoSDKLiveTranscription_Status_Start
originalLanguageMsgListener {"messageContent": "Hello.", "messageID": "4:0:16784384:0:514479993", "messageType": "ZoomVideoSDKLiveTranscription_OperationType_Add", "speakerID": "16784384", "speakerName": "Noah Shcenk", "timeStamp": 1769434918}
originalLanguageMsgListener {"messageContent": "Hello, how are you?", "messageID": "4:0:16784384:0:514479993", "messageType": "ZoomVideoSDKLiveTranscription_OperationType_Complete", "speakerID": "16784384", "speakerName": "Noah Shcenk", "timeStamp": 1769434918}

Live Transcription Status (from Web client)

{
  "isLiveTranscriptionEnabled": true,
  "isLiveTranslationEnabled": true,
  "isHostDisableCaptions": false,
  "isManualCaptionerEnabled": false,
  "transcriptionLanguage": "ar;zh-yue;zh;cs;da;nl;en;et;fi;fr-ca;fr;de;he;hi;hu;id;it;ja;ko;ms;fa;pl;pt;ro;ru;es;sv;tl;ta;te;th;tr;uk;vi;",
  "translationLanguage": [
    {
      "speakingLanguage": "de",
      "translatedToLanguage": "ar;zh-yue;zh;cs;da;nl;en;et;fi;fr-ca;fr;he;hi;hu;id;it;ja;ko;ms;fa;pl;ro;ru;es;sv;tl;ta;te;th;tr;uk;vi;"
    },
    {
      "speakingLanguage": "en",
      "translatedToLanguage": "ar;zh-yue;zh;cs;da;nl;et;fi;fr-ca;fr;de;he;hi;hu;id;it;ja;ko;ms;fa;pl;ro;ru;es;sv;tl;ta;te;th;tr;uk;vi;"
    }
    // ... other language pairs
  ]
}

Note: The translationLanguage array shows that when speakingLanguage is "de", the translatedToLanguage list does NOT include "de". However, when speakingLanguage is "en", German ("de") IS included in the translatedToLanguage list.

Questions

  1. Why does setTranslationLanguage('de') fail when speaking language is also ‘de’?

    • The documentation states this is a “common configuration”
    • Is this a restriction that the SDK enforces even though it’s documented as valid?
  2. Why do all caption payloads have language: 400 (NoTranslation)?

    • The React Native client successfully sets speaking and translation language to English
    • The React Native client speaks English
    • The Web client should receive translated captions in German, but instead receives language code 400
  3. Is there a different approach for cross-platform translation?

    • Web SDK user wants German translation
    • React Native SDK user speaks English
    • How should this be configured correctly?

Additional Context

  • Both clients are joining the same Zoom Video SDK session
  • Live transcription starts successfully on both clients
  • The React Native client receives original language messages via onOriginalLanguageMsgReceived
  • The Web client only receives captions with language: 400 regardless of settings
  • Everything works perfectly when both clients are set to english (except the lang code is 400)

Any help or guidance is much appreciated.
Thanks