Under which category would you file this issue?
Airflow Core
Apache Airflow version
not related to airflow version
What happened and how to reproduce it?
Steps to reproduce
breeze ui check-translation-completeness --language pl
Among the output you will see keys like dagRun_few/dagRun_many, etc. listed as unused:
Unused keys (not required, can be removed):
...
common.json:
assetEvent_few
assetEvent_many
asset_few
asset_many
backfill_few
backfill_many
createdAssetEvent_few
createdAssetEvent_many
dagRun_few
dagRun_many
Root cause
The logic in expand_plural_keys (dev/breeze/src/airflow_breeze/commands/ui_commands.py) skips expanding plural forms for a base key when none of the English values for that base contain the literal string {{count}}:
any_has_count = any(COUNT_PLACEHOLDER in en_key_to_value.get(k, "") for k in en_keys_for_base)
if not any_has_count:
continue
The English translations for dagRun are:
{
"dagRun_one": "Dag Run",
"dagRun_other": "Dag Runs"
}
Neither value contains {{count}}, so the script concludes no plural expansion is needed for non-English locales and marks dagRun_few / dagRun_many as unused.
However, i18next uses the count option passed to translate() for two independent purposes:
- Plural form selection — choosing
_one, _few, _many, _other based on the numeric value.
- Interpolation — inserting the number into the translated string via
{{count}}.
The script only accounts for purpose 2. Purpose 1 can occur even when {{count}} never appears in the string value. For example in TriggeredRuns.tsx (link):
translate("dagRun_other", { count: dagRuns.length })
Here count is passed solely to trigger plural form selection. For Polish:
- count: 2 → i18next selects
dagRun_few ("Wykonania")
- count: 6 → i18next selects
dagRun_many ("Wykonań")
Impact
Any locale with grammatical plural forms where the count is displayed separately (not via {{count}} inside the translation string) will have those keys incorrectly flagged as unused. Running --remove-unused would silently delete valid, necessary translations.
What you think should happen instead?
I suggest a bit more accurate heuristic for check-translation-completeness: if a key base already has multiple English plural forms (e.g. dagRun_other or dagRun_one exist in English), treat it as a plural key requiring all forms for the target language — regardless of whether {{count}} appears in the values.
Operating System
No response
Deployment
None
Apache Airflow Provider(s)
No response
Versions of Apache Airflow Providers
No response
Official Helm Chart version
Not Applicable
Kubernetes Version
No response
Helm Chart configuration
No response
Docker Image customizations
No response
Anything else?
No response
Are you willing to submit PR?
Code of Conduct
Under which category would you file this issue?
Airflow Core
Apache Airflow version
not related to airflow version
What happened and how to reproduce it?
Steps to reproduce
Among the output you will see keys like
dagRun_few/dagRun_many, etc. listed as unused:Unused keys (not required, can be removed): ... common.json: assetEvent_few assetEvent_many asset_few asset_many backfill_few backfill_many createdAssetEvent_few createdAssetEvent_many dagRun_few dagRun_manyRoot cause
The logic in
expand_plural_keys(dev/breeze/src/airflow_breeze/commands/ui_commands.py) skips expanding plural forms for a base key when none of the English values for that base contain the literal string{{count}}:The English translations for
dagRunare:{ "dagRun_one": "Dag Run", "dagRun_other": "Dag Runs" }Neither value contains
{{count}}, so the script concludes no plural expansion is needed for non-English locales and marksdagRun_few/dagRun_manyas unused.However, i18next uses the
countoption passed totranslate()for two independent purposes:_one,_few,_many,_otherbased on the numeric value.{{count}}.The script only accounts for purpose 2. Purpose 1 can occur even when
{{count}}never appears in the string value. For example inTriggeredRuns.tsx(link):Here
countis passed solely to trigger plural form selection. For Polish:dagRun_few("Wykonania")dagRun_many("Wykonań")Impact
Any locale with grammatical plural forms where the count is displayed separately (not via
{{count}}inside the translation string) will have those keys incorrectly flagged as unused. Running--remove-unusedwould silently delete valid, necessary translations.What you think should happen instead?
I suggest a bit more accurate heuristic for
check-translation-completeness: if a key base already has multiple English plural forms (e.g.dagRun_otherordagRun_oneexist in English), treat it as a plural key requiring all forms for the target language — regardless of whether{{count}}appears in the values.Operating System
No response
Deployment
None
Apache Airflow Provider(s)
No response
Versions of Apache Airflow Providers
No response
Official Helm Chart version
Not Applicable
Kubernetes Version
No response
Helm Chart configuration
No response
Docker Image customizations
No response
Anything else?
No response
Are you willing to submit PR?
Code of Conduct