DeepSeek Harness macOS menus stay English: missing plist

TroubleshootingPublished 2026-10-20Author: DeepSeek Plugin Market
DeepSeek HarnessmacOSCFBundleLocalizationselectron-builderlocalization
DeepSeek Harness macOS dialogs stay English when Info.plist lacks CFBundleLocalizations. Duplicate extendInfo keys dropped it. Merge, inject, or use one source.

If macOS is already set to Simplified Chinese and the Desktop interface is Chinese, but system items in the File menu and the folder dialog for adding a workspace remain English, read the installed app's Info.plist and check whether CFBundleLocalizations is present. According to Discussion #10343, the 0.2.1-rc.2 package lacks the key, and Contents/Resources has no .lproj directory, so the system treats the app as English-only. The root cause is not electron-builder; the build configuration declares the same object with two extendInfo keys.

Does the DeepSeek Harness Desktop Info.plist have CFBundleLocalizations

Run two commands before changing configuration so the facts are settled and a system language issue is not mistaken for a packaging issue. This works for both an installed app and a build artifact:

  1. Run plutil -p <app path>/Contents/Info.plist | grep CFBundleLocalizations, replacing <app path> with the install location. Expected: the command prints the array or nothing.
  2. Inspect the output. Expected: no output means the key is missing; an array means the key is not the problem.
  3. Run ls <app path>/Contents/Resources | grep lproj. Expected: the command prints .lproj entries or nothing.
  4. Inspect the output. Expected: also empty, so the bundle neither declares the language nor ships localized directories, and the system can only use English.
  5. Check that Simplified Chinese is first in System Settings > Language & Region. Expected: Chinese is the first preferred language, ruling out a configuration problem.

Which strings change in DeepSeek Harness when the key is missing

When the key is missing, the affected strings are not those the app renders itself but those the system localizes on the app's behalf. According to the discussion, the scope is roughly:

  1. Menu items macOS appends, such as Services and Show All Windows. Expected: they appear in English.
  2. The folder chooser opened for adding a workspace. Expected: buttons and labels come from the system in English.
  3. Standard system dialogs such as permission requests and file locations. Expected: also English.
  4. Text the app renders itself still follows the in-app i18n. Expected: a mix of Chinese and English.
  5. Switching the system language to English and back to Chinese. Expected: only system-localized content follows, while in-app text keeps the app setting.

Why DeepSeek Harness lost the key: two extendInfo keys in one object

According to the community's source review in the thread, the same object literal in electron-builder-config.mjs contains two extendInfo keys, and the later one overwrites the earlier one. This is not an electron-builder merge bug; it is ordinary JavaScript semantics. For other packaging checks, see macOS Desktop troubleshooting:

  1. The first extendInfo carried CFBundleLocalizations and the microphone usage description. Expected: it would have entered the build input.
  2. A later commit split it into two keys, and the second kept only NSMicrophoneUsageDescription. Expected: the earlier key is overwritten by the same property name.
  3. When the object literal is evaluated, the later key replaces the earlier one. Expected: CFBundleLocalizations never enters the build input.
  4. .oxlintrc.json ignores **/*.mjs. Expected: no-dupe-keys never runs on this file.
  5. The existing signing test asserts only the microphone description. Expected: neither check catches the missing key.

Three ways to restore CFBundleLocalizations in DeepSeek Harness Desktop

All three paths put the language declaration back into the bundle; they differ in whether you fix the build config, patch the built artifact, or collapse the configuration source. This is not a DSH plugin issue but a Desktop packaging issue; choose by whether you can rebuild.

Path 1: merge the extendInfo objects and keep the comment

This is the most direct root fix: one extendInfo carries both keys, and the comment explaining why the value must live in the bundle stays with it. The change is limited to build configuration and does not touch runtime.

  1. Open apps/desktop/scripts/electron-builder-config.mjs and locate the two extendInfo entries. Expected: both entries are located.
  2. Delete the second and merge NSMicrophoneUsageDescription into the first. Expected: one key remains with both properties.
  3. Keep the original comment explaining that macOS matches languages by bundle rather than by reading Electron Framework resources. Expected: the rationale stays documented.
  4. Rebuild and inspect the artifact with the two commands from the previous section. Expected: Info.plist contains both CFBundleLocalizations and the microphone description.
  5. Launch on a Chinese system. Expected: system menus become Chinese.
  6. Install the artifact on another Chinese Mac. Expected: the menu language follows the preferred language there too, not only on the build machine.
js
extendInfo: {
  CFBundleLocalizations: ['en', 'zh_CN'],
  NSMicrophoneUsageDescription:
    'DeepSeek Harness uses your microphone to transcribe speech into message drafts.',
},

Path 2: inject the key into the built plist

If the build configuration cannot change yet, the key can be added to the artifact, but it must be re-signed or the system will reject the app. This suits local verification or internal test builds:

  1. Back up the artifact first. Expected: the original artifact can be restored if injection fails.
  2. Create the array with /usr/libexec/PlistBuddy -c "Add :CFBundleLocalizations array". Expected: an empty array exists at the key.
  3. Add the two entries with -c "Add :CFBundleLocalizations:0 string en" and -c "Add :CFBundleLocalizations:1 string zh_CN". Expected: the array holds en and zh_CN.
  4. Run plutil -lint. Expected: the plist parses without errors.
  5. Re-run codesign with the original identity, preserving hardened runtime and entitlements. Expected: the signature covers the modified plist.
  6. Expected result: codesign --verify passes, the app launches, and system menu language follows the preferred language.

Path 3: make mac.extendInfo a single source

To prevent a duplicate key next time, collapse this configuration into one variable referenced in exactly one place. Then adding another key later cannot create two properties with the same name:

  1. Define const macExtendInfo = { ... } at the top of the configuration module. Expected: one object owns all mac bundle keys.
  2. Write extendInfo: macExtendInfo once in the mac configuration. Expected: the configuration has exactly one extendInfo property.
  3. If another build branch needs to extend it, merge with object spread. Expected: extensions merge into the same object instead of adding another key.
  4. Add lint coverage for .mjs files, or run no-dupe-keys separately against the build script. Expected: duplicate keys are reported before packaging.
  5. Rebuild and read the artifact once. Expected: extendInfo still appears once and the new key did not overwrite an old one.

DeepSeek Harness localization checks, regression, and signing

The same English text has different fixes: change the plist for the former, change translation resources for the latter. Use four comparisons to find the source, then verify in this order:

  1. The main interface is Chinese while system menus are English. Expected: this points to the bundle language declaration.
  2. The main interface itself has English. Expected: this points to missing in-app translation entries, not the plist.
  3. Only one third-party dialog is English. Expected: it may be that component's own language pack; do not change CFBundleLocalizations.
  4. Test under a different macOS user with Chinese as the preferred language. Expected: the result follows the system, confirming system-localized content.
  5. Add a test that reads the built Info.plist and asserts CFBundleLocalizations equals the expected array, plus NSMicrophoneUsageDescription is still present. Expected: both keys are covered.
  6. Launch on a Simplified Chinese system, check the folder dialog and appended menus, then run codesign --verify --deep --strict and spctl. Expected: language, permission description, and signature all pass together.
  7. Put the Info.plist check at the end of the packaging script. Expected: a failed build still reports which key is missing.

Source: Discussion #10343.

FAQ

On a Simplified Chinese macOS system, DeepSeek Harness Desktop menus are still English. Is the app not localized?

DeepSeek Harness macOS usually lacks a bundle language declaration rather than a translated interface. According to Discussion #10343, the Desktop interface can be Chinese, but system menus and folder dialogs that macOS and Chromium localize follow the app's CFBundleLocalizations. Without that key the system treats the app as English-only, so appended menu items stay English.

In DeepSeek Harness, how can I confirm CFBundleLocalizations is missing rather than the system language setting being ineffective?

In DeepSeek Harness, read the installed app's Info.plist directly. Run plutil -p /Applications/DeepSeek\ Harness.app/Contents/Info.plist and look for CFBundleLocalizations; no key means the bundle does not declare it. Then check whether Contents/Resources contains any .lproj directory; if both are missing, the system language is not the cause.

Why is CFBundleLocalizations written in DeepSeek Harness's electron-builder-config.mjs but absent from the build?

DeepSeek Harness's electron-builder-config.mjs contains two extendInfo keys in the same object literal. JavaScript keeps the later key, so only the microphone description takes effect and CFBundleLocalizations is dropped; electron-builder never receives two records. At the same time, .oxlintrc.json ignores *.mjs, so no-dupe-keys never reports it.

Why does editing Info.plist after building DeepSeek Harness break the app signature?

The DeepSeek Harness Info.plist is part of the signed content, so changing it invalidates the existing signature. After editing, re-sign and preserve the hardened runtime settings, then verify on the target machine. A temporary script injection suits local verification or internal builds, not replacing a release-signed artifact.

Can changing in-app translations fix the English system menus in DeepSeek Harness?

In DeepSeek Harness, changing in-app translations cannot fix English system menus, because system menus and folder dialogs follow CFBundleLocalizations, not the in-app i18n. Add the language declaration to Info.plist and re-sign; translation resources only affect text the app renders itself.

Related Terms

CFBundleLocalizations
CFBundleLocalizations is an Info.plist array key that declares the languages an app supports. macOS matches it against the system's preferred languages to decide which language to use for framework-localized content such as system menus and dialogs.— https://github.com/deepseek-ai/deepseek-harness/discussions/10343
extendInfo
`extendInfo` is an electron-builder mac option used to merge custom keys into the generated Info.plist. It is a JavaScript object property in the build configuration, and when the same property appears twice only the last one takes effect.— https://github.com/deepseek-ai/deepseek-harness/discussions/10343
Info.plist
Info.plist is the property list at the root of a macOS app bundle; it records the bundle identifier, version, supported languages, and permission usage descriptions. The system reads it to decide localization and permission behavior.— https://github.com/deepseek-ai/deepseek-harness/discussions/10343
.lproj
`.lproj` is the directory suffix for per-language resources inside a macOS app bundle, for example `zh_CN.lproj`. The directory only shows that resources are present; whether the system uses them still depends on the language declaration in Info.plist.— https://github.com/deepseek-ai/deepseek-harness/discussions/10343

Sources