Translatable text should be translated (LC0091)

Every translatable property and label variable in AL generates a translation ID. That ID must appear as a <trans-unit> in the project’s XLIFF files for each target language. When the entry is missing, empty, or still marked needs-translation, users in that locale see raw English text instead of a proper translation.

Example

table 50100 "Reward Program"
{
    fields
    {
        field(1; "Program Name"; Text[100])
        {
            Caption = 'Program Name'; // Missing translation for 'Table Reward Program - Field Program Name - Property Caption' in language(s): da-DK [LC0091]
        }
    }
}

Add the translation to the XLIFF file (Translations/MyApp.da-DK.xlf):

<trans-unit id="Table 2328808854 - Field 1296262074 - Property 2879900210"
            size-unit="char" translate="yes" xml:space="preserve">
  <source>Program Name</source>
  <target state="translated">Programnavn</target>
  <note from="Xliff Generator" annotates="general" priority="3">
    Table Reward Program - Field Program Name - Property Caption
  </note>
</trans-unit>

Translatable elements

ElementProperties checked
Tables, table extensions, enums, enum values, reports, XmlPorts, permission sets, profilesCaption
Table fieldsCaption, ToolTip
Pages, page extensions, queriesCaption, plus controls (Caption, ToolTip, OptionCaption) and actions (Caption, ToolTip)
Label variables (local and global)The label value
Report labelsThe label value

When the rule does not trigger

  • The label has Locked = true
  • The symbol is obsolete
  • No XLIFF files exist in the Translations/ directory
  • The translation already has a non-empty target without state="needs-translation"
  • The project manifest does not enable translation file generation

Configuration

Restrict which languages are checked by setting LanguagesToTranslate in alcops.json:

{
    "LanguagesToTranslate": ["da-DK", "de-DE"]
}

When omitted, the rule checks every XLIFF file in the Translations/ directory.

Extension objects

For extensions, translation IDs are generated relative to the translation root symbol, not the extension itself. When multiple extensions in the same app target the same base object, the compiler folds them under the extension with the lowest ID. This rule uses the same folding logic, so the reported translation IDs match exactly what the AL compiler generates.

See also