Skip to content

Fix malformed format specifiers in localized strings - #6695

Open
gpunto wants to merge 2 commits into
v6from
fix/v6-translation-format-specifiers
Open

Fix malformed format specifiers in localized strings#6695
gpunto wants to merge 2 commits into
v6from
fix/v6-translation-format-specifiers

Conversation

@gpunto

@gpunto gpunto commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Goal

Opening the delete channel confirmation dialog in the Compose UI kit crashes on Italian devices. The
translation reads canale% 1$s, which java.util.Formatter parses as a space flag plus width 1
followed by the conversion character $, so stringResource throws UnknownFormatConversionException.

Closes AND-1528

Implementation

  • Fix the Italian delete confirmation message to canale %1$s.
  • Replace the full-width in the Japanese delete and leave group confirmations. It is not
    recognised as a specifier, so those dialogs showed the literal %1$s instead of the channel name.
  • Replace %1d/%2d with %1$d/%2$d in the member count plurals across every locale. These parse
    as implicit argument plus minimum width. Latent rather than visible: the single argument cases render
    identically, and stream_ui_channel_list_member_info, where %2d would have padded a single digit
    with a leading space, has no code reference in the repo.

The crash and the full width case do not exist on develop, where these keys were reworked. The %1d
spelling does survive there in stream-chat-android-docs and the XML sample, carried over separately.

Testing

Parsed every values*/strings.xml in the repo the way Formatter does and checked for unparseable
specifiers, invalid conversion characters, full-width lookalikes and per-quantity argument count drift
against the default locale. The defects above were the only hits, and the pass is clean afterwards.

The crash was hit on a device running the demo app in Italian. Resource only change, so no code paths
move.

@gpunto gpunto added the pr:bug Bug fix label Sep 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled (or ignored for dependabot PRs).

🎉 Great job! This PR is ready for review.

@github-actions

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.26 MB 5.32 MB 0.05 MB 🟢
stream-chat-android-offline 5.49 MB 5.54 MB 0.05 MB 🟢
stream-chat-android-ui-components 10.64 MB 10.76 MB 0.11 MB 🟢
stream-chat-android-compose 12.87 MB 13.15 MB 0.28 MB 🟡

@gpunto
gpunto marked this pull request as ready for review September 11, 2026 13:37
@gpunto
gpunto requested a review from a team as a code owner September 11, 2026 13:37
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 6525e06e-850a-48ce-9234-7468d11d2c60

📥 Commits

Reviewing files that changed from the base of the PR and between 01619ef and a306627.

📒 Files selected for processing (19)
  • stream-chat-android-compose/src/main/res/values-en/strings.xml
  • stream-chat-android-compose/src/main/res/values-es/strings.xml
  • stream-chat-android-compose/src/main/res/values-fr/strings.xml
  • stream-chat-android-compose/src/main/res/values-hi/strings.xml
  • stream-chat-android-compose/src/main/res/values-it/strings.xml
  • stream-chat-android-compose/src/main/res/values-ja/strings.xml
  • stream-chat-android-compose/src/main/res/values/strings.xml
  • stream-chat-android-docs/src/main/res/values/strings.xml
  • stream-chat-android-ui-components-sample/src/main/res/values/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-en/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-es/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-fr/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-hi/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-id/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-in/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-it/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-ja/strings.xml
  • stream-chat-android-ui-components/src/main/res/values-ko/strings.xml
  • stream-chat-android-ui-components/src/main/res/values/strings.xml

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


Walkthrough

Localized Android resources now use valid indexed format specifiers for member counts, online counts, and selected-channel confirmation messages across Compose, UI components, sample, and documentation modules.

Changes

String format corrections

Layer / File(s) Summary
Compose resource formatting
stream-chat-android-compose/src/main/res/values*/strings.xml
Compose member-count placeholders now use %1$d. Italian and Japanese confirmation messages use corrected ASCII placeholders and spacing.
UI component resource formatting
stream-chat-android-ui-components/src/main/res/values*/strings.xml
Member-count and online-count plural resources now use indexed integer placeholders such as %1$d and %2$d.
Sample and documentation resources
stream-chat-android-docs/src/main/res/values/strings.xml, stream-chat-android-ui-components-sample/src/main/res/values/strings.xml
Member-count resources now use indexed integer placeholders.

Priority: ➖ Normal

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to a3066

The localization fixes correct malformed format strings without changing code paths or introducing active merge risk.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description clearly explains the Italian crash, lists the implementation changes, links the issue, and documents testing. It omits the UI Changes, contributor checklist, reviewer checklist, and GI…
Title check ✅ Passed The title is concise, clear, and directly describes the main change: correcting malformed format specifiers in localized strings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/v6-translation-format-specifiers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks each counted sign
And sets the little dollars in line
Member numbers hop and shine
Messages gain their proper design
The strings now format fine!

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

@andremion andremion left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, the fix is correct and I did not find anything left over.

Separate from the diff: lint already flags all three of these as StringFormatCount, but no workflow runs a lint task, so the warnings were never seen. Would it be worth adding lint to CI for the translatable modules, or is that its own ticket?

Comment thread stream-chat-android-docs/src/main/res/values/strings.xml
@gpunto

gpunto commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Thanks! On the lint point: it is already running on PRs, it just is not visible from this repo. pr-checks.yml calls the shared android-ci.yml in stream-build-conventions-android, and its static checks job runs ./gradlew lint next to spotless and apiCheck. Same setup on v6 and on develop.

And it does catch this. I put the broken Italian string back and ran :stream-chat-android-compose:lintDebug: the build succeeds, and the report contains

values-it/strings.xml:65: Inconsistent number of arguments in formatting string stream_compose_selected_channel_menu_delete_conversation_confirmation_message; found both 0 here and 1 in values/strings.xml

as a StringFormatCount warning. That check is a warning by default, so the job stays green and the report goes unread next to the other ~110 warnings in the module.

So the useful change is promoting those ids to errors, something like error += "StringFormatCount" alongside the existing disable += lines, rather than wiring lint in. Narrow enough not to drag in the whole warning backlog. I will open a separate ticket for it.

@gpunto

gpunto commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Filed as AND-1529.

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

Labels

pr:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants