Latest build Android 1.6.0 (9) · 6 Aug 2026 https://qa.techsoftwarevn.com/namuchat/apk/NamuChat-1.6.0-b9-arm64.apk Download APK

NamuChat · QA Handoff · Revision 2

Bug Fix Report

Response to the Namu bug tracking sheet (19 findings). The Android app and the backend server have both been updated. Thirteen findings are fixed and live; the rest are listed with exactly what is still missing and why.

Updated 6 Aug 2026 Scope Android + server Server deployed 6 Aug 2026 Reported against 1.6.0(5)
13Fixed and live
1Partly fixed — needs mail server
2Should be fixed — confirm
3Still open

Download the test build


Android 1.6.0 (build 9). Pick ARM64 unless you know the device needs something else — it covers essentially every phone from the last several years.

Uninstall the existing app first

This build is signed with a test key. Installing it over a copy of NamuChat from the store will fail with a signature conflict. Remove the old app, then install this one.

Two behaviours that are intentional, not defects

  • The SMS code fills itself in. After 2–10 seconds the verification code appears on its own. That is a convenience in test builds only; the store build shows the code in a banner for you to type.
  • One-tap registration is hidden. The carrier credential is not configured in this build, so registration falls back to the SMS code flow.

Read this first


Correction to the previous revision

The earlier version of this report listed several findings as "fixed earlier — please re-test". That was true of the source code but not of the running server. The production backend was still running a build from 3 June and therefore contained none of those fixes — anything you re-tested before today would still have failed.

The server was updated on 6 August 2026. Everything below is now actually live. Please disregard any earlier test results on server-side items.

You need a fresh Android build

The Android changes are not in any APK issued so far. Install the new build before testing. It is signed with a test key, so uninstall the existing NamuChat first — installing over the top will fail with a signature conflict.

Test everything in all three languages

Much of this round is language handling. Switch under Me → Settings → Language and re-run the auth flows in Chinese, English and Vietnamese. A bug that only appears in English or Vietnamese is exactly the class of problem this round targets.

Verified against production, not just in the lab

Each server-side fix below was checked by calling the live API after deployment. The actual responses are quoted in the relevant entries so you can reproduce them.

Fixed and live


Thirteen findings are resolved. Each entry gives the underlying cause, what changed, and the steps to confirm it.

Bug_003 / Bug_005 Error messages displayed in the wrong language Fixed Android · Server
Cause

Three separate faults stacked on top of each other. The Android app never told the server which language it wanted, so the server always answered in Chinese. Every error message built into the app was itself a hardcoded Chinese string. And the server's Vietnamese translation file was missing 50 entries, so even a correct request fell back to Chinese.

Changed

The app now sends its selected language with every request. All in-app error text moved into the translation files. On the server, Vietnamese and Traditional Chinese were completed — all four languages now carry an identical 167 entries, enforced by an automated test so the gap cannot silently return.

Verified live
POST /api/auth/login  (wrong password)

Accept-Language: en-US
"Incorrect username or password"

Accept-Language: vi
"Tên đăng nhập hoặc mật khẩu không đúng"

Accept-Language: zh-CN
"用户名或密码错误"
  1. Set the app to English, sign in with a wrong password — error in English.
  2. Turn on airplane mode and retry — network error also in English.
  3. Repeat both in Vietnamese.
  4. Confirm no Chinese remains on the sign-in or registration screen.
Bug_013 Searching for "%" returns every user Fixed Server
Cause

% and _ are wildcards in the database's search language. Typed into a search box they were passed straight through and matched every record. This was a genuine data-exposure issue, not just a cosmetic one.

Changed

Fixed in the people search — and in five further places the original fix had missed: organisation member search (which had no protection at all and would list an entire company's staff), message search in two places, and the AI knowledge base in two places. Empty searches now return nothing instead of everything.

Verified live
search "%"  → 1 result
   (exactly the 1 account whose nickname
    genuinely contains a "%" character)

search "_"  → 20 results, capped
   (55 accounts genuinely contain "_")

Before the fix, "%" returned an
arbitrary page of the user list.
  1. In people search enter % — must not return a general list.
  2. Try _ and an empty string.
  3. Repeat inside organisation member search if you have a company account.
  4. Repeat in message search.
Bug_012 Username search returns inaccurate results Fixed Server
Cause

Two faults. People search matched the login name, the ID and the email — but never the display nickname, which is the name you actually see on screen. Separately, a nickname chosen during registration was thrown away before it reached the database, so most accounts had no nickname to find.

Changed

Nickname now participates in the search and the real nickname is returned rather than a copy of the login name. Registration now stores the nickname — confirmed by registering a live test account and reading it back.

How to verify
  1. Register a new account with a distinct nickname.
  2. From a different account, search that nickname — the user must be found.
  3. Change the nickname, then search the new value.
  4. Existing accounts created before today may still have no nickname stored.
Bug_008 CSRF error when signing in with a non-existent account Fixed iOS · PC
Cause

A security check was supposed to skip the sign-in and registration endpoints, but a path-matching mistake meant it never actually skipped them. Any device carrying a leftover session cookie got a CSRF error instead of a proper "account does not exist" message.

Status

Fixed with an automated regression test, and now actually deployed — this fix was written before your last test pass but was never live until today.

How to verify
  1. Sign in with an account that does not exist.
  2. You must see a normal credentials error, never the word "CSRF".
  3. Repeat after signing out of a previous session on the same device.
Bug_007 / Bug_011 Registration accepts special characters and unlimited length Fixed Android · Server
Changed

The server enforces the rules and the Android app now checks as you type, so the problem is caught before a round trip. Username is limited to letters, digits, underscore, hyphen and Chinese characters, 2–32 characters; nickname to 30 characters. The Register button stays disabled until the value is valid.

Verified live
POST /api/auth/register
username = "admin@#$%"

"Username may only contain letters,
 digits, underscore, hyphen or
 Chinese characters"
How to verify
  1. Enter admin@#$% as a username — inline message, button disabled.
  2. Try %, a space and an emoji — all rejected.
  3. Enter a 1-character username, then paste 40 characters — both rejected.
  4. Paste a 40-character nickname — rejected.
  5. Confirm all messages are translated in each language.
Bug_009 Password field keeps its value when switching between Sign in and Register Fixed iOS · Android
Cause

The tab control only changed which fields were visible. A password typed on one tab stayed loaded on the other.

Changed

Switching tabs clears the password and dismisses any leftover error.

How to verify
  1. On Sign in, type any password, switch to Register — field must be empty.
  2. Type a different password, switch back — empty again.
  3. Trigger a failed sign-in, then switch tabs — the red error must disappear.
Bug_004 Terms of Service and Privacy Policy open in the wrong language Fixed iOS · Android
Cause

The apps opened the policy pages as plain links, so the language was decided by the phone's browser, not by the app. A phone set to Chinese with the app set to English still showed Chinese policies.

Changed

The app passes its own language to the page. Choosing "Follow system" deliberately keeps the old behaviour.

How to verify
  1. Set the phone to Chinese and the app to English.
  2. Tap Privacy Policy on the sign-in screen — must open in English.
  3. Tap Terms of Service — also English.
  4. Set the app back to Chinese, confirm both open in Chinese.

Known limit: the policy pages exist only in Chinese and English. In Vietnamese the app requests English.

Bug_014 Interface only available in Chinese Fixed PC · Android
Cause

Reported on desktop, but the Android sign-in and registration screen had the same problem: labels and buttons were written into the code in Chinese instead of coming from the translation files.

Changed

Every label, button, hint and placeholder on the auth screens now comes from the translation files, with matched coverage across all three languages — 187 entries each, verified automatically.

How to verify
  1. Switch to English, reopen the sign-in screen.
  2. Check both tabs, the consent line, "Get code" and "Forgot password?".
  3. Open Forgot password and step through all three of its screens.
  4. Repeat in Vietnamese. Report any remaining Chinese.
Bug_010 Changing the avatar does nothing Fixed iOS
Cause

The upload succeeded, but the server's reply did not match what the iOS app expected, so the app treated a successful save as a failure and discarded it.

Status

Fixed on the server and now deployed. Android and web were never affected.

How to verify
  1. Change the avatar on iOS — must update immediately.
  2. Force-quit and reopen — must persist.
  3. Confirm a contact on another device sees the new avatar.
Bug_002 Register button active while required fields are empty Fixed iOS
Status

Fixed on iOS. Android already behaved correctly and now additionally blocks submission on invalid usernames and nicknames.

How to verify

Open Register with all fields empty — the button must not be pressable. Fill fields one at a time and watch when it becomes active.

Note

On Android, registration also requires a phone number, an SMS code and the consent checkbox. That is intended.

New Two-factor screen could trap the user on an expired challenge Fixed Android
Cause

Found while fixing Bug_003. The two-factor screen decided whether to send the user back to password entry by searching the server's error text for specific Chinese words. Once the server began replying in English or Vietnamese — exactly what the Bug_003 fix causes — that check would never match, and a user with an expired challenge would have been stuck retrying forever.

Changed

The decision no longer depends on language. It uses the response status and an attempt counter that mirrors the server's five-attempt limit.

How to verify
  1. Enable two-factor on a test account, in English.
  2. Sign in, then enter a wrong code five times.
  3. You must be returned to the password screen, not left on the code screen.
  4. Repeat in Vietnamese — behaviour must be identical.
New Company membership was never actually saved Fixed Server
Cause

Not in your sheet — found while fixing the nickname problem, which shares a root cause. The routine that saves a user account silently discarded two fields it was handed. Besides the nickname, this meant creating a company, joining one by invite code, switching between companies, and single sign-on assignment all did nothing. Four features that appeared to work but never stored anything.

How to verify
  1. Create a company account — the creator must appear as a member.
  2. Join a company with an invite code — membership must persist after signing out and back in.
  3. Switch between companies and confirm the choice sticks.

Partly fixed


Bug_006 Forgot Password does nothing Partly fixed iOS · Android
Cause

Traced to the end. The apps collect an email address at registration and send it correctly, but the server never stored it. Password recovery then found no email on file and — by design, to avoid revealing whether an account exists — reported success without sending anything. The screen advanced to "enter your code" and no code ever arrived.

The scale of it: of 225 existing accounts, exactly one had an email address stored.

What is fixed

Registration now validates and stores the email address, and rejects one that is already in use — confirmed by registering a live test account and reading it back from the database. Format errors are reported properly:

email = "not-an-email"
"Invalid email address"
What is still missing

No mail server is configured, so nothing can actually be sent. Password recovery currently returns a clear "email service is not configured" error — honest, but not working. This is a deliberate decision to defer, not an oversight.

Also note: even once mail is configured, the 225 accounts that already exist still have no email address. They will need to add one under Me → Edit profile, or have an administrator reset the password. Only accounts registered from today onward can use password recovery. Please test with a newly created account.

Please confirm


We believe these are resolved but cannot prove it from the code alone. Please test and report explicitly rather than assuming.

Bug_016 / Bug_017 Cannot register or sign in on desktop Confirm PC
Reasoning

These likely share a root cause with Bug_008. Browsers keep cookies between visits, which is precisely the condition that triggered the faulty security check — so desktop was hit hardest. That fix is now live.

How to verify
  1. Register a new account on desktop in a normal window.
  2. Sign out and sign in again in the same window.
  3. Repeat in a private window, which starts with no cookies.
  4. Note any difference between the two — that difference is the key detail.
If it still fails

We need the browser name and version, and whatever appears in the browser's developer console at the moment it fails.

Still open


Please keep these open — do not close them after testing this build.

Bug_001 No phone number registration Open on iOS iOS
Status

Android already supports this — phone number plus SMS code is required to register, with one-tap carrier registration where available. iOS still has no phone option. The groundwork exists but no screen uses it, so this is unfinished work rather than a defect.

How to verify
  1. On Android, register with a phone number and SMS code end to end.
  2. Confirm "Get code" is disabled until the number is valid, then counts down 60 seconds.
  3. On iOS, confirm the option is still missing and keep the finding open.
Bug_019 Cannot sign in on Android devices Worked around Android
Cause

Fully identified. The release build's code-shrinking rules were written against the wrong package name, so they protected nothing. Shrinking then renamed the structures used to read server responses and every API call failed to parse — including sign-in. Debug builds were unaffected, which is why it only appeared on installed release builds.

Status

Currently avoided by turning code shrinking off. Sign-in works, but this is a workaround, not a repair — the corrected rules exist but have never been verified on a device.

What we need from you
  1. Confirm sign-in works on the current build on real hardware.
  2. When shrinking is re-enabled, a second pass is needed: sign in, open the chat list, open contacts, and confirm all three load real data.
  3. Empty lists after that change are the signature of this bug returning.
Bug_015 / Bug_018 Inconsistent interface between platforms Needs a reference PC · iOS · Android
Why it is stuck

These cannot be judged from the code. Mobile and desktop are built with different interface toolkits, so some difference is unavoidable and expected.

What would unblock it

A reference design, or screenshots marking the specific differences that matter — spacing, button placement, iconography, wording. Split into concrete findings rather than one broad one.

Suggestion

Start with sign-in and registration. Every platform was just changed there, and it is the first thing every user sees.

Full status at a glance


ID Finding Platform Status
Bug_001No phone number registrationiOSOpen on iOS
Bug_002Register button active when fields emptyiOSFixed
Bug_003Error messages in wrong languageiOS · Android · ServerFixed
Bug_004Terms and Privacy in wrong languageiOS · AndroidFixed
Bug_005Sign-in errors in wrong languageiOS · Android · ServerFixed
Bug_006Forgot Password does nothingiOS · AndroidPartly — no mail server
Bug_007Special characters accepted in usernameiOS · Android · ServerFixed
Bug_008CSRF error on unknown accountiOS · PCFixed
Bug_009Password kept across tab switchiOS · AndroidFixed
Bug_010Avatar change does nothingiOSFixed
Bug_011No length limit on name and usernameiOS · Android · ServerFixed
Bug_012Username search inaccurateServerFixed
Bug_013Search "%" returns everythingServerFixed
Bug_014Interface only in ChinesePC · AndroidFixed
Bug_015Interface differs, mobile vs desktopPCNeeds a reference
Bug_016Cannot register on desktopPCConfirm
Bug_017Cannot sign in on desktopPCConfirm
Bug_018Interface differs, iOS vs AndroidAllNeeds a reference
Bug_019Cannot sign in on AndroidAndroidWorked around

Bug_003 and Bug_005 are the same fault reported on two screens, so they share a status. The sheet leaves the ID column blank from row 9 onward; those rows were numbered in order as Bug_009 through Bug_019, and the numbering matches the fixes in the code.

Deployment record


For the development team.

Server, 6 August 2026

The production backend had been running a build from 3 June and was updated in place. Four outstanding database changes were applied first, each checked beforehand against live data — no duplicate records stood in the way and no rows were removed. The user count was unchanged at 225 before and after. A full database backup and a copy of the previous build were taken first, so the change can be reversed in under a minute. Service interruption was roughly three seconds.

Health checks passed afterwards, and a readiness endpoint that returns not found on the old build now responds correctly — direct confirmation that the new version is the one running.

Android

res/values/strings.xml · +53 entries, Chinese
res/values-en/strings.xml · +53 entries, English
res/values-vi/strings.xml · +53 entries, Vietnamese
data/api/ApiClient.kt · language sent with every request
util/Errors.kt · error text moved to resources
ui/auth/LoginScreen.kt · translation, validation, tab reset, policy links
ui/auth/ForgotPasswordScreen.kt · translation
ui/auth/TwoFactorScreen.kt · translation, language-independent retry logic

Server

_core/oauth.ts · registration stores email, with validation and duplicate check
db/connection.ts · stop discarding nickname and company assignment
db/users.ts · search includes nickname; exact email lookup added
ops/tenant.ts, db/messages.ts, messaging/message-ops.ts,
db/extras.ts, services/ai-service.ts · wildcard escaping in five more places
i18n/vi.json · +52 entries · i18n/zh-TW.json · +69 entries
__tests__/ · language coverage now enforced for every language; wildcard escaping locked down

Type checking is clean and the full suite passes — 200 tests across 18 files.

Recommended next