Translatable text should be translated
Properties like Caption and ToolTip, as well as Label variables, are translatable by default — the compiler generates a unique translation ID for each one. For users in other locales to see translated text, each ID must have a matching <trans-unit> entry in the project’s XLIFF files. When the entry is missing, empty, or still marked needs-translation, those users see raw source-language text instead: a caption that should read Programnavn in Danish displays as Program Name.
Add or complete the <trans-unit> entry in each target language’s XLIFF file.
Example
table 50100 "Reward Program"
{
fields
{
field(1; "Program Name"; Text[100])
{
Caption = 'Program Name'; // Translatable text should be translated [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>When the diagnostic is reported
| Element | Properties checked |
|---|---|
| Tables, table extensions, enums, enum values, reports, XmlPorts, permission sets, profiles | Caption |
| Table fields | Caption, ToolTip |
| Pages, page extensions, queries | Caption, plus controls (Caption, ToolTip, OptionCaption) and actions (Caption, ToolTip) |
| Label variables (local and global) | The label value |
| Report labels | The label value |
By default, the rule checks every XLIFF file in the Translations/ directory. Restrict which languages are checked by setting LanguagesToTranslate in alcops.json:
{
"LanguagesToTranslate": ["da-DK", "de-DE"]
}For extension objects, 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.
Exception
The rule does not trigger when:
- The label or property has
Locked = true. This is the intended mechanism for text that should remain in the source language — API field names, technical identifiers, or format strings. - No XLIFF files exist in the
Translations/directory. - The project manifest does not include
"TranslationFile"in thefeaturesarray.
When a translatable property cannot use Locked but should remain untranslated, suppress with a pragma:
#pragma warning disable LC0091 // Internal tooling page, not exposed to end users
Caption = 'Debug Panel';
#pragma warning restore LC0091See also
- Working with Translation Files on Microsoft Learn
- Translations Overview on Microsoft Learn