Skip to content

fix(locale): strip POSIX encoding suffix from macOS locale vars to prevent ICU crash#1664

Open
tpaustin wants to merge 1 commit intogeneralaction:mainfrom
tpaustin:fix/macos-locale-icu-crash
Open

fix(locale): strip POSIX encoding suffix from macOS locale vars to prevent ICU crash#1664
tpaustin wants to merge 1 commit intogeneralaction:mainfrom
tpaustin:fix/macos-locale-icu-crash

Conversation

@tpaustin
Copy link
Copy Markdown

@tpaustin tpaustin commented Apr 4, 2026

Summary

  • Strips POSIX encoding suffixes (e.g. .UTF-8) from locale env vars after initialization on macOS, catching values from any source (existing env, shell detection, or fallback)
  • Changes getFallbackUtf8Locale() on darwin to return en_US instead of en_US.UTF-8
  • Updates LSEnvironment in package.json to use en_US so the Info.plist value is also ICU-safe before any JS runs
  • Updates tests to reflect the suffix-stripped expectations on macOS

Background

Issue #1633 reports that Emdash crashes on launch on macOS 26+ starting from 0.4.44, and the crash persists through 0.4.45.

The crash stack is:

libicucore    uloc_getTableStringWithFallback  ← null pointer dereference
Foundation    Locale.characterDirection(forLanguage:)
UIFoundation  +[NSParagraphStyle _defaultWritingDirection]
AppKit        +[NSApplication _defaultUserInterfaceLayoutDirection]
AppKit        -[NSCocoaMenuImpl initWithMenu:]

Root cause: ICU's uloc_getTableStringWithFallback on macOS 26+ crashes when it receives a locale string with a POSIX encoding suffix like .UTF-8. ICU expects bare locale identifiers (en_US, not en_US.UTF-8). On older macOS, Foundation silently stripped the encoding suffix before passing it to ICU; on macOS 26 this stripping no longer happens.

PR #1632 changed the fallback from C.UTF-8 to en_US.UTF-8, and PR #1640 added LSEnvironment with en_US.UTF-8 — but any .UTF-8 suffix triggers the same crash. macOS always uses UTF-8 regardless of locale, so the suffix is both redundant and harmful.

Compatibility: The fix is fully backwards compatible. Stripping .UTF-8 from en_US.UTF-8en_US is semantically a no-op on macOS (all macOS locales are UTF-8). Older macOS versions tolerated the suffix; newer ones do not. The stripped value is what ICU always expected.

Test plan

  • pnpm exec vitest run src/main/utils/__tests__/shellEnv.test.ts — all 15 tests pass
  • pnpm exec vitest run — all 863 tests pass
  • pnpm run build passes
  • pnpm run type-check passes
  • App launches without crash (pnpm run dev — confirmed clean startup with no segfault)

Closes #1633

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced macOS locale and language environment variable handling by normalizing locale identifiers to properly align with macOS system requirements, improving overall system compatibility and ensuring consistent behavior across different language and regional configurations
    • Refined how environment variables for locale-dependent features are configured to provide better support for regional customization and language settings on macOS

…event ICU crash

On macOS 26+, ICU's uloc_getTableStringWithFallback crashes with a null
pointer dereference when locale strings contain POSIX encoding suffixes
(e.g. "en_US.UTF-8"). ICU expects bare locale identifiers like "en_US"
and does not understand the ".UTF-8" encoding marker.

The previous fix (PR generalaction#1640) changed the fallback from C.UTF-8 to
en_US.UTF-8, but any .UTF-8 suffix triggers the same crash path in the
newer macOS 26 ICU. macOS always uses UTF-8 regardless of locale, so
the suffix carries no information and only breaks ICU lookup.

Changes:
- Strip POSIX encoding suffixes from all locale env vars after locale
  initialization on macOS (applied as a final pass in
  initializeShellEnvironment so it catches values from any source:
  existing env, shell detection, or fallback)
- Change getFallbackUtf8Locale() on darwin to return "en_US" (no suffix)
- Change LSEnvironment in package.json to use "en_US" / "en_US" so the
  Info.plist value is also ICU-safe before any JS runs
- Update tests to reflect suffix-stripped expectations on macOS

Closes generalaction#1633

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 4, 2026

@tpaustin is attempting to deploy a commit to the General Action Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 4, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74386456-bb72-4920-9eb5-0163b933f907

📥 Commits

Reviewing files that changed from the base of the PR and between 6a89f67 and 3039d33.

📒 Files selected for processing (3)
  • package.json
  • src/main/utils/__tests__/shellEnv.test.ts
  • src/main/utils/shellEnv.ts

📝 Walkthrough

Walkthrough

The pull request updates macOS locale environment variable handling to strip POSIX encoding suffixes. Changes include modifying build configuration to use en_US instead of en_US.UTF-8, adding a platform-specific sanitization function to remove encoding suffixes from locale values, and updating tests to reflect platform-dependent locale formatting expectations.

Changes

Cohort / File(s) Summary
Build Configuration
package.json
Modified macOS extended Info settings to change LANG and LC_CTYPE locale values from en_US.UTF-8 to en_US.
Shell Environment Utilities
src/main/utils/shellEnv.ts
Added sanitizeLocaleForPlatform() helper to strip POSIX encoding suffixes (e.g., .UTF-8) on macOS. Updated getFallbackUtf8Locale() to return en_US instead of en_US.UTF-8. Extended initializeShellEnvironment() to sanitize locale environment variables on macOS.
Shell Environment Tests
src/main/utils/__tests__/shellEnv.test.ts
Updated locale expectations to be platform-dependent: macOS tests use stripped locale values (e.g., C, en_US), while non-macOS tests use UTF-8 suffixed values. Added strip() helper for test-specific locale normalization.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 Locale suffixes gone with a swish,
macOS gets its .UTF-8 wish,
en_US strips bare and clean,
The smoothest environment we've seen! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: fixing locale environment variables on macOS by stripping POSIX encoding suffixes to prevent ICU crashes.
Linked Issues check ✅ Passed The PR directly addresses issue #1633 by fixing the segfault caused by locale strings with POSIX encoding suffixes, implementing the root cause fix across shell environment initialization, fallback locale, and package.json configuration.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the macOS locale/ICU issue: package.json LSEnvironment values, locale sanitization logic, fallback locale behavior, and corresponding test updates.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

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

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: Segfault starting on 0.4.44

1 participant