Repository navigation
[Bug][macOS] v1.2.3 → v1.2.4 内置更新失败:codesign requirement 缺少 "=" 与 "field." #753
Copy link
Copy link
Closed
Description
问题描述
macOS 桌面端从 v1.2.3 更新至 v1.2.4 时,更新包下载、DMG 校验和挂载均成功,但应用内更新反复失败,界面只显示:
安装更新失败,请稍后再试。
排查发现失败发生在生成的 macOS 更新辅助脚本的开发者身份校验阶段。签名本身有效,是 codesign -R 的 requirement 参数存在两处语法问题。
环境
- macOS 27.2(26B123)
- Apple Silicon / arm64
- 原安装:Memmy v1.2.3 国内版,位于
/Applications/Memmy.app - 目标安装包:
Memmy-1.2.4-darwin-arm64-cn-signed.dmg(官方 GitHub Release) - Bundle ID:
cn.memtensor.memmy - 已安装版本和官方目标包的 TeamIdentifier 均为
S7NLXHGBJ2
复现步骤
- 使用官方签名的 v1.2.3 国内版。
- 在「设置 → 关于」检查并安装 v1.2.4 更新。
- 下载后进入 staging,签名身份校验失败。
- 再次重试仍然失败,版本保持 v1.2.3。
更新日志中的关键错误
~/Library/Application Support/Memmy/updates/mac-update-install.log:
anchor apple generic and identifier "cn.memtensor.memmy" and certificate leaf[1.2.840.113635.100.6.1.13] exists and certificate leaf[subject.OU] = "S7NLXHGBJ2": No such file or directory
invalid requirement specification
Memmy update does not have the installed Apple Developer ID identity
主进程日志同时记录:
download app update failed Error: Error invoking remote method 'memmy:download-update': Error: helper script exited with code 1
根因及独立验证
代码位置:
macBundleValidationScript() 生成的 requirement 包含:
certificate leaf[1.2.840.113635.100.6.1.13] exists
随后执行:
/usr/bin/codesign --verify --deep --strict -R "$signing_requirement" "$app_path"两处问题已在本机独立验证:
- 缺少 literal requirement 前缀
=。codesign将没有此前缀的参数作为 requirement 文件路径,因此报No such file or directory。 - 证书扩展 OID 缺少
field.前缀。 仅补上=后仍报:应使用error: invalid or corrupted code requirement(s) Requirement syntax error(s): line 1:80: unexpected char: '.'certificate leaf[field.1.2.840.113635.100.6.1.13] exists。
对官方 v1.2.4 应用执行以下修正后的命令,验证通过:
/usr/bin/codesign --verify --deep --strict \
-R '=anchor apple generic and identifier "cn.memtensor.memmy" and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and certificate leaf[subject.OU] = "S7NLXHGBJ2"' \
/Applications/Memmy.app另外,原始 codesign --verify --deep --strict 检查通过,spctl --assess --type execute --verbose=2 返回 accepted / source=Notarized Developer ID。官方国内版 DMG 的 SHA-256 也与 Release 元数据一致:
e607497b38d2cd04189e5abea7b291cf124a656b677dabb867178699c323dd71
因此,这次失败不应被归类为实际的开发者身份不匹配。
预期行为及修复建议
- 合法、同开发者签名的官方更新包应能正常完成 staging 和安装。
- requirement 同时修正 literal 前缀与 OID 字段语法,保留现有 Bundle ID、Apple Developer ID、TeamIdentifier 和完整签名检查。
- 为共享的 staging / install 校验路径补充真实 macOS
codesign验证,覆盖合法同团队包通过、错误团队或 Bundle ID 的包仍被拒绝。 - UI 在更新失败时提供具体错误或日志入口,避免只显示“请稍后再试”。
临时处理及验证范围
已在核验官方安装包签名、公证和哈希并备份用户数据后,手动完成同渠道 v1.2.4 更新;原账户和数据保留,应用「关于」显示当前已是最新版本,Memory service 2.1.7 健康检查通过。
v1.2.4 打包产物及提交反馈时的 main 中仍包含上述校验代码。尚未验证 v1.2.4 到后续版本的应用内升级;这里报告的是实际发生的 v1.2.3 → v1.2.4 失败,以及对校验命令的独立复现。
Reactions are currently unavailable
Activity
Memtensor-AI commentedon Oct 26, 2026
🤖 AutoDev has picked up this issue and started working on it.
Task ID:
d93c34215c89cf05Working branch:
bugfix/autodev-753-20261026235019878Target branch:
mainWorkflow: AutoDev (coding → PR)
I will post the PR link here once done. If I need more information, I will ask in the comments.
fix(desktop): repair macOS update codesign requirement and expose upd…
Memtensor-AI commentedon Oct 27, 2026
✅ AutoDev task
d93c34215c89cf05completed.Summary: Fixes issue #753: macOS in-app updates from v1.2.3 to v1.2.4 failed because the generated update helper passed a malformed codesign requirement.
Root cause and fix (App/shell/desktop/src/main/mac-update-scripts.ts): the requirement string handed to
codesign --verify -Rhad two syntax errors — it lacked the literal "=" prefix (so codesign interpreted it as a requirement file path and reported "No such file or directory") and the Developer ID certificate extension OID lacked thefield.prefix (parser error "unexpected char: '.'"). A new exportedbuildMacSigningRequirement()builds the literal requirement as=anchor apple generic and identifier "cn.memtensor.memmy" and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and certificate leaf[subject.OU] = "<team>", and is now the single source for both the stage and install helper scripts. The existing bundle-ID, Developer ID extension, TeamIdentifier and fullcodesign --verify --deep --strictchecks are all retained; the unsigned-build path is unchanged. Values containing quotes or backslashes are rejected instead of being spliced into the generated shell script.Tests (App/shell/desktop/tests/mac-update-scripts.test.ts, gated to macOS, plus cross-platform assertions): (1) the generated requirement starts with "=", uses
field.<oid>, and contains the bundle ID / subject.OU clauses; (2) both helper scripts embed the corrected literal and no longer contain the legacy forms; (3) unsigned builds omit the team requirement; (4) realcodesignverification of ad-hoc-signed .app fixtures proves the corrected value is treated as an inline requirement (no ENOENT / "unexpected char"), reproduces both legacy failures exactly as reported, matches the bundle ID and rejects a different one; (5) a throwaway self-signed identity (TeamIdentifier in subject.OU + Developer ID extension OID, in a temporary keychain) confirms a same-team package passes the team/extension clauses while a foreign team, foreign bundle ID, or missing extension is rejected, and that the full shipped requirement parses (only the Apple anchor excludes the synthetic fixture). A mock-codesign test also asserts the helper forwards the literal requirement string to-R. App/shell/desktop/tests/packaged-runtime-boundary.test.ts was extended to lock in the new IPC channel.UI (App/frontend/desktop): update failures now carry a
showLogsflag, and the About tab renders a "查看更新日志 / View update logs" action beside the error instead of only "安装更新失败,请稍后再试。". Newmemmy:open-update-logsIPC +openUpdateLogs()preload bridge opens the updates directory containingmac-update-install.log, where the concrete reason is recorded. New zh/en message keysettings.about.openUpdateLogs; settings-page test covers error, prepared-with-failure, success (no link), and English rendering.Verification:
tsc --noEmitclean for App/shell/desktop and App/frontend/desktop; eslint reports 0 errors (only pre-existing warnings); targeted suites pass — shell mac-update-scripts + packaged-runtime-boundary + windows-update-validation (115 passed, 28 macOS-skipped on this Linux runner), frontend settings-page + i18n + model-config parity (103 passed). Known unrelated pre-existing failures on this Linux runner: Reactactis not a function in several App/frontend/desktop/src/app interaction tests and a computer-use-agent-restart test (both reproduce on a clean tree); Electron-dependent shell suites cannot load electron on Linux. The new macOS-only codesign tests were not executed here and will run on macOS CI.Base branch:
mainBranch:
bugfix/autodev-753-20261026235019878Commit:
ac8d05fPR: #754
Assigned to: @XiaohuiSu
syzsunshine219 commentedon Oct 28, 2026
This issue has been fixed in v1.2.401. You can download the latest installation package. If you are unable to update, you can download the installation package from the official website and overwrite the existing installation with the latest package