Pushkal-Gupta opened a new pull request, #75326:
URL: https://github.com/apache/airflow/pull/75326
Seven labels in the UI show a translation key instead of a sentence.
Set a pool name longer than 256 characters and the validation error reads:
> pools.form.rules.nameMaxLength
It should read "Name can contain a maximum of 256 characters". That string
already exists, and is already translated into all 21 languages. The form just
asks for it by the wrong name.
## What a user sees today
Each of these keys is missing from the `en` bundles, so i18next renders the
key itself:
| Where | Key asked for | What is shown |
| --- | --- | --- |
| Pool form validation | `admin:pools.form.rules.nameMaxLength` |
`pools.form.rules.nameMaxLength` |
| Config form error | `common:error.unknown` | `error.unknown` |
| Connection form error | `common:error.unknown` | `error.unknown` |
| Dag code page | `dag:dagDetails.bundleVersion` |
`dagDetails.bundleVersion` |
| XCom column header | `dashboard:timestamp` | `timestamp` |
| Table sort button | `components:sort` | `sort` |
| Dag schedule | `dags:schedule.asset` | `schedule.asset` |
Those are real outputs, read off an i18next instance built from the `en`
bundles.
## Three different causes
**Two ask for a string that exists under another name.**
`pools.form.nameMaxLength` and `common:error.defaultMessage` are both present
and translated in all 21 locales, so correcting the call restores the text in
every language at once.
In `PoolForm.tsx` the line above already gets it right:
```js
required: translate("pools.form.nameRequired"),
validate: (_value) => _value.length <= 256 ||
translate("pools.form.rules.nameMaxLength"),
```
The extra `rules.` reads like it came from the `rules: {}` object the call
sits in. No locale has ever defined `pools.form.rules`, and `common:error` has
`defaultMessage` but never had `unknown`.
**Three were never written.** `dagDetails.bundleVersion`,
`xcom.columns.timestamp` and `components:sort` do not exist in any locale, so
this adds them to `en` and leaves the other languages to translators, as usual.
The XCom header was also reaching into the `dashboard` namespace for a column
title; it now sits with the `dag`, `key` and `value` headers it belongs to.
**One is a comparison that can never be true.** `Schedule.tsx` chose between
two views with:
```js
timetableSummary === translate("schedule.asset")
```
`timetableSummary` comes from the server as
`AssetTriggeredTimetable.summary`, which is the fixed literal `"Asset"`.
Comparing it to a translated string is wrong even with the key in place,
because a translator localising that word would break the check in their
language. With the key missing it compares against `"schedule.asset"` and never
matches. It now compares against the literal, with a comment recording where
the value comes from.
This one has stayed hidden because the `||` before it means the asset view
still appeared whenever `asset_expression` was set.
## The test
`locales.test.ts` gains one check: walk every `.ts` and `.tsx` file under
`src/`, collect the namespaces each file loads and every literal key it passes
to `translate(...)`, and assert i18next can resolve them. It fails without this
change and names all seven. Keys built by interpolation are skipped, as they
only exist at run time.
It asks i18next rather than reimplementing the lookup, which turned out to
matter. My first attempt reported 52 failures, nearly all wrong, because a
hand-rolled check misses three things the real resolver handles:
- plural-only keys, stored as `foo_one` and `foo_other` with no plain `foo`
- flat keys that contain dots, like `"limitedList.allItems"` in
`components.json`
- a file listing several namespaces, all of which i18next searches, not just
the first
`exists(key, { count: 1 })` gets all three right. The counter-placeholder
tests already in this file build an instance the same way.
Nothing checked this before. `locales.test.ts` only verified counter
formatting, which is why seven keys could drift.
## Checks
- 1961 UI tests pass, 239 files
- `eslint` and `tsc` clean
- the new check reports 0 missing of 1256 keys after the change, 7 before
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes - Claude Code (Opus 5)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]