fix(locale): duplicate en-US key crashes boot under jsonv2 (#696/#728) #743

Merged
jmiller merged 1 commits from fix/locale-dup-key-jsonv2 into dev 2026-07-05 20:32:28 +00:00
Owner

Second fresh-boot crash (after the code-scanner panic in #742)

With the code-scanner panic fixed, the dev container booted further but still crash-looped, now on:

InitLocales [E] Failed to set messages to en-US: jsontext: duplicate object member name "repo.settings.event_delete"

The binary is built with go1.26.4-X:jsonv2. Go 1.26's v2 JSON decoder rejects duplicate object keys; the old v1 decoder silently kept the last value. locale_en-US.json had repo.settings.event_delete twice:

  • the canonical webhook-event key ("Delete", with its event_delete_desc sibling), used by webhook/settings.tmpl;
  • a second "Branch Deletion" added by the branch-protection delete feature (#696/#728), used by protected_branch.tmpl — it reused the existing key name.

Under the old decoder the last value won (so the webhook label wrongly showed "Branch Deletion"); under jsonv2 it's fatal.

Fix

  • Rename the branch-protection entry to its own key repo.settings.protect_branch_deletion ("Branch Deletion") and point templates/repo/settings/protected_branch.tmpl at it. The webhook keeps event_delete = "Delete". Both labels render correctly and the JSON has no duplicate.
  • Proactively scanned every tracked options/**/*.json (locale + fileicon) for duplicate keys — en-US was the only affected file; all now clean.
  • Verified no non-tracked custom locale/JSON overrides exist on the host (the container loads baked files); the fork's .moko-customization-baseline.json is valid.

Only en-US had the duplicate; other locales fall back to en-US for the new key.

Same latent-defect class as #742 — only a real boot surfaces it. Present on main too (via #696/#728); a companion main fix will bundle the boot fixes.

https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT

## Second fresh-boot crash (after the code-scanner panic in #742) With the code-scanner panic fixed, the dev container booted further but still crash-looped, now on: ``` InitLocales [E] Failed to set messages to en-US: jsontext: duplicate object member name "repo.settings.event_delete" ``` The binary is `built with go1.26.4-X:jsonv2`. **Go 1.26's v2 JSON decoder rejects duplicate object keys**; the old v1 decoder silently kept the last value. `locale_en-US.json` had `repo.settings.event_delete` **twice**: - the canonical **webhook-event** key (`"Delete"`, with its `event_delete_desc` sibling), used by `webhook/settings.tmpl`; - a second `"Branch Deletion"` added by the branch-protection delete feature (#696/#728), used by `protected_branch.tmpl` — it reused the existing key name. Under the old decoder the last value won (so the webhook label wrongly showed "Branch Deletion"); under jsonv2 it's fatal. ## Fix - Rename the branch-protection entry to its own key `repo.settings.protect_branch_deletion` ("Branch Deletion") and point `templates/repo/settings/protected_branch.tmpl` at it. The webhook keeps `event_delete` = "Delete". Both labels render correctly and the JSON has no duplicate. - **Proactively scanned every tracked `options/**/*.json` (locale + fileicon) for duplicate keys** — en-US was the only affected file; all now clean. - **Verified no non-tracked custom locale/JSON overrides exist on the host** (the container loads baked files); the fork's `.moko-customization-baseline.json` is valid. Only en-US had the duplicate; other locales fall back to en-US for the new key. > Same latent-defect class as #742 — only a real boot surfaces it. Present on `main` too (via #696/#728); a companion main fix will bundle the boot fixes. https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
jmiller added 1 commit 2026-07-05 20:27:08 +00:00
fix(locale): duplicate en-US key crashes server boot under jsonv2
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 41s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
PR RC Release / Build RC Release (pull_request) Successful in 3s
Universal: PR Check / Validate PR (pull_request) Successful in 13s
Generic: Project CI / Lint & Validate (pull_request) Successful in 47s
Universal: PR Check / Secret Scan (pull_request) Successful in 1m39s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
Generic: Project CI / Tests (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
98b1ed2f7b
The branch-protection delete feature (#696/#728) added a second
"repo.settings.event_delete" entry ("Branch Deletion") to locale_en-US.json,
reusing the existing webhook-event key (value "Delete"). The old JSON decoder
silently kept the last value; Go 1.26's jsonv2 decoder rejects duplicate
object keys, so InitLocales fails ("duplicate object member name
repo.settings.event_delete") and the server crash-loops at startup. Like the
code-scanner regexp panic, this only surfaces on a fresh boot, which is why it
shipped unnoticed.

Give the branch-protection section header its own key
"repo.settings.protect_branch_deletion" and point protected_branch.tmpl at it,
so the webhook "Delete" label and the branch-protection "Branch Deletion"
header both render correctly and the JSON has no duplicate. Verified: no
duplicate keys remain in any options/locale/*.json.

Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT
jmiller merged commit 3efbab985b into dev 2026-07-05 20:32:28 +00:00
jmiller deleted branch fix/locale-dup-key-jsonv2 2026-07-05 20:32:30 +00:00
Sign in to join this conversation.