{"record":{"id":"80d9c149d69431cb","repo":"instructure/canvas-lms","slug":"translation-samelanguagetranslationerror","errorCode":null,"errorMessage":"Translation::SameLanguageTranslationError","messagePattern":"Translation::SameLanguageTranslationError","errorType":"exception","errorClass":"Translation::SameLanguageTranslationError","httpStatus":null,"severity":"warning","filePath":"lib/translation.rb","lineNumber":123,"sourceCode":"          content: html_string,\n          target_language: tgt_lang,\n          feature_slug:,\n          root_account_uuid:,\n          current_user:\n        )\n\n        check_same_language(translation_response.source_language, tgt_lang)\n        collect_translation_stats(src_lang: translation_response.source_language, tgt_lang:, type: feature_slug)\n        translation_response.translation\n      end\n    end\n\n    private\n\n    def check_same_language(source, target)\n      if source == target\n        InstStatsd::Statsd.distributed_increment(\"translation.errors\", tags: [\"error:same_language\"])\n        raise Translation::SameLanguageTranslationError\n      end\n    end\n\n    def collect_translation_stats(src_lang:, tgt_lang:, type:)\n      tags = %W[type:#{type} source_language:#{src_lang} dest_language:#{tgt_lang}]\n      InstStatsd::Statsd.distributed_increment(\"translation.invocations\", tags:)\n    end\n\n    def handle_cedar_errors\n      yield\n    rescue => e\n      case e.class.name\n      when /SameLanguageTranslationError/\n        raise SameLanguageTranslationError\n      when /ContentTooLongError/\n        raise TextTooLongError\n      when /UnsupportedLanguageError/\n        raise UnsupportedLanguageError","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/translation.rb#L105-L141","documentation":"After a Cedar translation completes, Translation#check_same_language compares the detected source language with the requested target language and raises Translation::SameLanguageTranslationError when they are identical — translating text to the language it is already in is rejected as a no-op. Stats are incremented under translation.errors before raising.","triggerScenarios":"Calling Translation.translate_text or translate_html where Cedar's detected source_language equals tgt_lang — e.g. translating an English message with tgt_lang:'en', or user-selected target language matching auto-detected content language (including exact string equality like 'pt-BR' vs 'pt-BR'; a variant mismatch such as 'en' vs 'en-US' would not trigger).","commonSituations":"Users asking to 'translate' a message already in their language; auto-translate features detecting language after the UI already committed a target; seeded/default tgt_lang matching the content locale; case or code-format mismatches that resolve to equal language IDs.","solutions":["Compare the detected source language to tgt_lang before requesting translation and skip when equal","In UIs, disable the translate action when the target language matches the content language","Rescue Translation::SameLanguageTranslationError and return the original text untranslated","Normalize language codes (region variants) consistently on both sides before comparison"],"exampleFix":"# before\ntranslated = Translation.translate_text(text: msg, tgt_lang: 'en', options: opts)\n# after\nbegin\n  translated = Translation.translate_text(text: msg, tgt_lang: tgt, options: opts)\nrescue Translation::SameLanguageTranslationError\n  translated = msg # already in target language\nend","handlingStrategy":"try-catch","validationCode":"# only call when target differs from known/detected source language\nnext if detected_source_language.to_s == tgt_lang.to_s","typeGuard":null,"tryCatchPattern":"begin\n  translated = Translation.translate_text(text: text, tgt_lang: tgt_lang, options: opts)\nrescue Translation::SameLanguageTranslationError\n  translated = text\nend","preventionTips":["Detect content language before offering translation","Disable the translate action for matching locales","Normalize language-code formats on both sides","Return original content as a graceful fallback"],"tags":["translation","i18n","same-language","cedar"],"backgroundTag":"unsupported-operation","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}