Russian locale: extraShort durations render 5m as «5млн» (millions) due to msgid "m" collision
@JoshuaKGoldberg is already working on this.
Since Sep 18, 2026.
- Dominant language
- Python
- Stars
- 44.8k
- Forks
- 4.9k
- Avg merge
- 21h 23m
- Merged PRs (30d)
- 607
Description
Problem Statement
Single-character msgid "m" is used for three different meanings across the codebase:
- Millions —
small_count()insrc/sentry/templatetags/sentry_helpers.py:207:z = [(1000000000, _("b")), (1000000, _("m")), (1000, _("k"))] - Month label —
DURATION_LABELS.min theabsValue >= MONTHextraShort branch (static/app/utils/duration/getDuration.tsx:101) - Minute label —
DURATION_LABELS.min theabsValue >= MINUTEextraShort branch (static/app/utils/duration/getDuration.tsx:143)
Because gettext has no context (msgid "m" maps to one msgstr per locale), the Russian catalog carries the millions translation for all three:
#: static/app/utils/duration/getDuration.tsx:35
#: templatetags/sentry_helpers.py:165
msgid "m"
msgstr "млн" # «million» — correct only for small_count()
Impact: with unitStyle="extraShort" (TimeSince → getRelativeDate → getDuration), durations under 1 month render in Russian as «5млн» ("5 millions") instead of «5м» ("5 min"). Months render as «3млн» instead of «3м».
Steps to Reproduce
- Set the Sentry UI language to Russian
- Open any view using
TimeSince unitStyle="extraShort"— e.g. Traces tables (static/app/views/explore/tables/tracesTable/fieldRenderers.tsx:619), Profiling slowest functions (slowestFunctionsWidget.tsx:374), Explore conversations (conversationsTable.tsx:399), or project custom filters (static/app/views/settings/project/projectFilters/customFilters.tsx:1033) - Observe relative times < 1 month
Expected Result
5m → «5мин» (or «5м»), matching the short-style label.
Actual Result
5m → «5млн»
Suggested Fix
Give duration labels their own msgids (and pgettext contexts where single letters are ambiguous), e.g. in DURATION_LABELS:
m: t('m'), // month extra-short -> pgettext('duration', 'mo') or similar
…splitting the month/minute single-letter labels from the number abbreviation used by small_count(), then re-running makemessages. Alternative minimal option: stop using t('m') for durations in favor of the existing distinct keys (t('mo') already exists for months; a new distinct single-letter key for minutes would be needed) so translators can map them independently of the count abbreviations.
Related: #98565 (same family of short-label translation problems; fixed for "min" by the Transifex sync in #76385).
Product Area
Issues
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with static/app/utils/duration/getDuration.tsx and src/sentry/templatetags/sentry_helpers.py to trace the duration labels and the separate small_count() abbreviation. Inspect the Russian catalog and the existing t('mo') key, then rerun makemessages after choosing distinct duration msgids or contexts. Done means Russian extraShort minutes and months no longer render as «млн», while the millions abbreviation remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, react, typescript
- Domain
- frontend, internationalization, localization
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100