Skip to content

fix(i18n-es): correct stranded translations in API key and semantic layer catalogs - #43080

Draft
glaterza wants to merge 1 commit into
apache:masterfrom
glaterza:fix/i18n-es-stranded-feature-clusters
Draft

fix(i18n-es): correct stranded translations in API key and semantic layer catalogs#43080
glaterza wants to merge 1 commit into
apache:masterfrom
glaterza:fix/i18n-es-stranded-feature-clusters

Conversation

@glaterza

@glaterza glaterza commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

Two recently-added features — API keys and semantic layers / views — shipped with near-totally stranded Spanish catalogs. pybabel update's fuzzy matcher copies a translation from a similar-looking msgid; when it guesses wrong, the Spanish ends up saying something the English never said.

Every entry corrected here is flagged #, fuzzy. Both the frontend and backend builds compile with --use-fuzzy, so all of these are live in the UI today — the flag means "needs review", not "withheld".

This is the same defect class as #42808, applied to two feature clusters deliberately left out of it: correcting one toast to say capa semántica while 33 neighbours still said capa de anotación would have read worse than being consistently wrong.

These are not judgement calls about my Spanish. The correct terminology already exists in this catalog on non-fuzzy entries, and the fuzzy entries contradict it:

Already in the catalog, not fuzzy Contradicted by, fuzzy
An error occurred while fetching semantic layers → "…las capas semánticas" Semantic Layer → "Capa de anotación"
%s Semantic View → "%s Vista semántica" Semantic view does not exist → "El conjunto de datos no existe"
API keys allow scoped programmatic access to Superset. → "Las claves API…" API Keys → "Clave privada"
Physical → "Físico" Semantic → "Correo electrónico"

So the change is verifiable by a reviewer who does not read Spanish: it makes the fuzzy entries agree with the reviewed entries already in the file.

The worst of the set, all user-facing:

msgid Was Literally Now
Inactive Activo "Active" — inverted Inactivo
Semantic Correo electrónico "Email" Semántico
Create API Key Creado por "Created by" Crear clave API
Expired Explorar "Explore" Caducado
Last Used Listar usuarios "List users" Último uso
Definition desviación "deviation" Definición
Revoked Trazado "Plotted" Revocado
API Keys Clave privada "Private key" Claves API
Mapbox (API key required) El correo electrónico es obligatorio "Email is required" Mapbox (requiere clave API)
Failed to fetch API keys No se han podido etiquetar los elementos "Could not tag the items" No se han podido recuperar las claves API
Add %s view(s) %s opción(es) "%s option(s)" Añadir %s vista(s)
Semantic layer does not exist El gráfico no existe "The chart does not exist" La capa semántica no existe
Are you sure you want to revoke this API key? This action cannot be undone. ¿Seguro que quieres eliminar las anotaciones seleccionadas? "…delete the selected annotations?" ¿Seguro que quieres revocar esta clave API? Esta acción no se puede deshacer.

Inactive → "Activo" is the one I would most like a second pair of eyes on: it is a status badge asserting the opposite of the truth.

On gender. The API key status column is headed Estado and renders one of Active / Inactive / Expired / Revoked. Active → "Activo" is shared with the alert & report list, so it is effectively fixed masculine; the other three agree with it (and with estado) rather than with the feminine clave. Mixing genders down one column would be worse than either choice made consistently.

Scope. 64 entries: 63 get a corrected msgstr, and one (API key name is required) was already correct Spanish carrying a stale fuzzy flag. Every msgid was checked to be used only inside features/apiKeys/, features/semanticViews/, or features/semanticLayers/, so nothing here changes wording elsewhere in the app.

Deliberately excluded:

  • Entries carrying a backfill_po.py attribution comment (12 in these clusters). Those are machine-translated drafts awaiting the review step in docs/developer_docs/contributing/howtos.md; their problem is register, not meaning, and mixing them in would blur two different claims.
  • features/semanticLayers/label.ts, which swaps "dataset" → "datasource" and "database" → "data connection" when the flag is on. All eight alternate labels currently collapse to the single string "Conexiones de la base de datos" regardless of case or number, so lower case mid-sentence uses render capitalised and plural. That is a real defect, but a different one (case/number correctness rather than stranding), so it is left for a follow up.

On how these were found, including what the method misses. #42808 used a similarity heuristic: a fuzzy entry whose msgstr is byte-identical to another entry's, where the two msgids are dissimilar. That heuristic is structurally blind to the case where a legitimate synonym shares the stranded translation — Revoke → "Eliminar" never surfaces, because Remove → "Eliminar" is correct and so the pair scores as similar. Lowering the threshold does not help; a synonym is supposed to score similar.

Roughly a fifth of the entries here — including Inactive, Expired, Last Used, Definition and Done — were found instead by enumerating every t() call in these three feature directories and diffing that set against the catalog, then opening the running UI and reading the screens. Neither the msgid text nor the similarity score would have flagged them.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

TESTING INSTRUCTIONS

Both features are behind default-off flags, so enable them first:

FEATURE_FLAGS = {"SEMANTIC_LAYERS": True, "FAB_API_KEY_ENABLED": True}
FAB_API_KEY_ENABLED = True

Set the language to Spanish, then visit Settings → API Keys (/user_info/) and the Semantic Layer entry on the database connections page.

The catalog still compiles, and the entry counts move by exactly the 64 touched:

msgfmt -c --statistics -o /dev/null superset/translations/es/LC_MESSAGES/messages.po
# master: 3931 translated, 978 fuzzy, 197 untranslated
# here:   3995 translated, 914 fuzzy, 197 untranslated

Only one of the 64 entries (Add %s view(s)) contains a format placeholder, and its specifier set is unchanged. msgfmt only checks format strings on non-fuzzy entries, so the check that proves clearing the flags introduced nothing is a blanket un-fuzzy of the whole file:

sed -E 's/^#,(.*)fuzzy(.*)$/#,\1\2/' \
  superset/translations/es/LC_MESSAGES/messages.po > /tmp/t.po
msgfmt -c -o /dev/null /tmp/t.po

That reports 4 fatal errors on this branch and 4 on master — the same pre-existing ones (%s column, %s item, Added to 1 dashboard, %(suggestion)s instead of …), untouched here.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

…ayer catalogs

Two recently-added features shipped with near-totally stranded Spanish
catalogs. `pybabel update`'s fuzzy matcher copied translations from
unrelated entries, so the Spanish says something the English does not.

Every entry corrected here is `#, fuzzy`, and both the frontend and
backend builds compile with `--use-fuzzy`, so all of these are live in
the UI today.

The corrections are not judgement calls: the correct terminology already
exists in this catalog on non-fuzzy entries, and the fuzzy entries
contradict it.

  "An error occurred while fetching semantic layers"
      -> "...las capas semanticas"     (not fuzzy, correct)
  "Semantic Layer" -> "Capa de anotacion"  ("Annotation layer")

  "%s Semantic View" -> "%s Vista semantica"  (not fuzzy, correct)
  "Semantic view does not exist" -> "El conjunto de datos no existe"

  "API keys allow scoped programmatic access to Superset."
      -> "Las claves API..."           (not fuzzy, correct)
  "API Keys" -> "Clave privada"        ("Private key")

Worst of the set, all user-facing:

  "Inactive"                  -> "Activo"              (inverted)
  "Semantic"                  -> "Correo electronico"  ("Email")
  "Create API Key"            -> "Creado por"          ("Created by")
  "Expired"                   -> "Explorar"            ("Explore")
  "Last Used"                 -> "Listar usuarios"     ("List users")
  "Definition"                -> "desviacion"          ("deviation")
  "Revoked"                   -> "Trazado"             ("Plotted")
  "Mapbox (API key required)" -> "El correo electronico es obligatorio"
  "Are you sure you want to revoke this API key? ..."
      -> "Seguro que quieres eliminar las anotaciones seleccionadas?"

The API key status column is headed "Estado" and renders one of Active /
Inactive / Expired / Revoked. "Active" -> "Activo" is shared with the
alert and report list, so it is fixed masculine; the other three agree
with it rather than with the feminine "clave".

Scope is limited to msgids used only within these two features, so no
wording changes elsewhere in the app. Entries carrying a backfill_po.py
attribution comment are excluded: those are machine-translated drafts
awaiting a separate review step, and their problem is register rather
than meaning.

Also folds in "Client ID" and "Slice Id", raised in review of apache#42808.
Both were stranded from "Line width" ("Anchura de la linea"), alongside
the "Client Secret" that apache#42808 already corrected.

Only one of the 64 entries contains a format placeholder, and its
specifier set is unchanged, so clearing the fuzzy flags introduces no new
msgfmt format errors: the blanket un-fuzzy check reports the same 4
pre-existing fatal errors as master.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added i18n Namespace | Anything related to localization i18n:spanish Translation related to Spanish language labels Aug 11, 2026
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.57%. Comparing base (d91ca50) to head (8e7dc76).

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #43080      +/-   ##
==========================================
- Coverage   66.57%   66.57%   -0.01%     
==========================================
  Files        2866     2866              
  Lines      162322   162322              
  Branches    37353    37353              
==========================================
- Hits       108067   108064       -3     
- Misses      52188    52190       +2     
- Partials     2067     2068       +1     
Flag Coverage Δ
hive 38.16% <ø> (ø)
mysql 57.76% <ø> (ø)
postgres 57.80% <ø> (-0.01%) ⬇️
presto 40.13% <ø> (ø)
python 59.19% <ø> (-0.01%) ⬇️
sqlite 57.42% <ø> (ø)
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

i18n:spanish Translation related to Spanish language i18n Namespace | Anything related to localization size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant