getsentry / getsentry/sentry

Russian locale: extraShort durations render 5m as «5млн» (millions) due to msgid "m" collision

Open
#124,240 4 comments 0 reactions 0 assignees View on GitHub

@JoshuaKGoldberg is already working on this.

Since Sep 18, 2026.

Bug Product Area: Explore
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:

  1. Millionssmall_count() in src/sentry/templatetags/sentry_helpers.py:207: z = [(1000000000, _("b")), (1000000, _("m")), (1000, _("k"))]
  2. Month labelDURATION_LABELS.m in the absValue >= MONTH extraShort branch (static/app/utils/duration/getDuration.tsx:101)
  3. Minute labelDURATION_LABELS.m in the absValue >= MINUTE extraShort 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" (TimeSincegetRelativeDategetDuration), 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
  1. Set the Sentry UI language to Russian
  2. 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)
  3. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.