Bug description
superset/translations/messages.pot is the extraction template every language catalog is updated
from. It has drifted from source: 428 translatable strings exist in the code but are absent from
the template, and 109 strings remain in the template but no longer exist in source.
Because a string only reaches the 30 .po catalogs via the template, those 428 strings cannot be
translated into any language. They are not untranslated-pending-a-volunteer; they are invisible to
translators and to the AI backfill alike.
Measured at c426186a2e:
|
count |
committed messages.pot |
5117 |
fresh pybabel extract from source |
5436 |
| in source, not in the template |
428 |
| in the template, no longer in source |
109 |
Raw set difference is 429 / 110; the figures above exclude whitespace-only variants, so they are
real drift rather than formatting churn.
Examples of strings users see but no translator can reach: % of column total, %s chart updated,
%s dataset updated, Add to favorites, %s MCP scopes, A rule with this name already exists.
Reproduction
# clean tree matters: generated files left in the working tree corrupt this measurement
git status --porcelain # must be empty
pybabel extract -F superset/translations/babel.cfg -o /tmp/fresh.pot \
--no-location --sort-output \
--copyright-holder=Superset --project=Superset \
-k _ -k __ -k t -k tn:1,2 -k tct .
# compare the msgid sets of /tmp/fresh.pot and superset/translations/messages.pot with Babel
# (collapse whitespace before comparing to discount wrapping-only variants)
Expected: the committed template matches a fresh extraction, give or take strings added since the
last regeneration.
Actual: it is 428 strings behind, and the gap grows with every PR that adds a translatable string.
Why it persists
The template has not been regenerated since 2026-09-02 (e8540b7c49). Nothing fails when it
goes stale:
.github/workflows/superset-translations.yml runs babel_update.sh on base and PR and compares
translated/fuzzy counts in the .po catalogs via check_translation_regression.py. It never
compares the committed template against a fresh extract, and the regression step is
continue-on-error: true. So a PR that adds a translatable string without regenerating the
template is indistinguishable from one that does.
A related symptom: superset/translations/do-not-translate.txt lists 27 msgids, but a current run
stamps only 24 markers — pivoted_xlsx, step-after and step-before are listed yet no longer
extractable from source. Same root cause.
Possible directions
Not proposing an implementation here, but the options seem to be:
- Regenerate the template (and propagate to the catalogs) as a one-off, which fixes today's gap but
not tomorrow's.
- Add a CI check that fails when the committed template differs from a fresh extract — the missing
guard, and the only option that stops it recurring.
- Regenerate the template on a schedule.
Happy to open the PR for whichever direction maintainers prefer; (1) and (2) together seem like the
useful pair.
Screenshots/recordings
Not applicable — build-pipeline defect, nothing renders.
Superset version
master / latest-dev
Python version
3.11
Node version
Not applicable
Browser
Not applicable
Additional context
Measured with pybabel 2.17.0 (the version pinned in requirements/base.txt) and GNU gettext 1.0,
on a clean tree asserted both before and after extraction.
Raised from discussion #43562, where
@rusackas suggested tracking it separately. Related but independent: #44395 repairs the msgcat
normalization step in babel_update.sh, and #44397 adds translator context comments. Neither
changes the drift measured here.
Checklist
Bug description
superset/translations/messages.potis the extraction template every language catalog is updatedfrom. It has drifted from source: 428 translatable strings exist in the code but are absent from
the template, and 109 strings remain in the template but no longer exist in source.
Because a string only reaches the 30
.pocatalogs via the template, those 428 strings cannot betranslated into any language. They are not untranslated-pending-a-volunteer; they are invisible to
translators and to the AI backfill alike.
Measured at
c426186a2e:messages.potpybabel extractfrom sourceRaw set difference is 429 / 110; the figures above exclude whitespace-only variants, so they are
real drift rather than formatting churn.
Examples of strings users see but no translator can reach:
% of column total,%s chart updated,%s dataset updated,Add to favorites,%s MCP scopes,A rule with this name already exists.Reproduction
Expected: the committed template matches a fresh extraction, give or take strings added since the
last regeneration.
Actual: it is 428 strings behind, and the gap grows with every PR that adds a translatable string.
Why it persists
The template has not been regenerated since 2026-09-02 (
e8540b7c49). Nothing fails when itgoes stale:
.github/workflows/superset-translations.ymlrunsbabel_update.shon base and PR and comparestranslated/fuzzy counts in the
.pocatalogs viacheck_translation_regression.py. It nevercompares the committed template against a fresh extract, and the regression step is
continue-on-error: true. So a PR that adds a translatable string without regenerating thetemplate is indistinguishable from one that does.
A related symptom:
superset/translations/do-not-translate.txtlists 27 msgids, but a current runstamps only 24 markers —
pivoted_xlsx,step-afterandstep-beforeare listed yet no longerextractable from source. Same root cause.
Possible directions
Not proposing an implementation here, but the options seem to be:
not tomorrow's.
guard, and the only option that stops it recurring.
Happy to open the PR for whichever direction maintainers prefer; (1) and (2) together seem like the
useful pair.
Screenshots/recordings
Not applicable — build-pipeline defect, nothing renders.
Superset version
master / latest-dev
Python version
3.11
Node version
Not applicable
Browser
Not applicable
Additional context
Measured with
pybabel2.17.0 (the version pinned inrequirements/base.txt) and GNU gettext 1.0,on a clean tree asserted both before and after extraction.
Raised from discussion #43562, where
@rusackas suggested tracking it separately. Related but independent: #44395 repairs the
msgcatnormalization step in
babel_update.sh, and #44397 adds translator context comments. Neitherchanges the drift measured here.
Checklist
included it here as text in the "additional context" section.