Summary
Recent Discord Stable macOS builds appear to have changed the cold-boot / first-bootstrap host-app handoff enough that OpenAsar's current macOS retention behavior can break fresh installs.
The short version: Discord now appears to require the ShipIt bootstrap handoff to clear with the stock staged app. If OpenAsar patches app.asar inside the staged app-0.0.xxx/Discord.app before ShipIt finishes, Discord can loop or never reach the usable client.
Observed on Discord Stable macOS 0.0.396. Other channels/builds may be affected if they use the same ShipIt handoff path.
Reproduction shape
This is the failure pattern I can reproduce from a clean first-bootstrap state:
- Remove Discord updater-managed install state while preserving login/settings data:
installer.db
ShipIt_request.json
0.0.xxx/
app-0.0.xxx/
modules/
module_data/
download/
Cache/
Code Cache/
- Replace the channel app's
Contents/Resources/app.asar with OpenAsar before Discord's first post-cleanup launch.
- Launch Discord and let it download/stage the host update.
- Allow OpenAsar's current macOS retention path to copy itself into the staged app:
app-0.0.xxx/Discord.app/Contents/Resources/app.asar
- Discord can then loop or fail to complete the final ShipIt move/relaunch.
The same machine completes the flow if the first bootstrap is allowed to run with stock Discord first. After that stock handoff completes once, OpenAsar can be injected into the final app and Discord launches normally.
Expected behavior
- Discord stages the stock host app under the channel App Support folder.
- ShipIt moves/commits that stock staged app into the final app bundle.
- OpenAsar restores itself into the final channel app after ShipIt completes.
- Discord relaunches into the usable client.
Final app examples:
/Applications/Discord.app/Contents/Resources/app.asar
/Applications/Discord PTB.app/Contents/Resources/app.asar
/Applications/Discord Canary.app/Contents/Resources/app.asar
Actual behavior
With current upstream-style staged-app injection:
- OpenAsar patches the staged
app-0.0.xxx/Discord.app before ShipIt finishes.
- ShipIt may never complete the final app replacement.
- The staged app and
ShipIt_request.json can remain behind.
- Discord loops or never reaches the usable client.
This points more toward a staged-app ShipIt/bootstrap validation issue than a normal OpenAsar runtime issue. OpenAsar still works in the final app after a stock handoff completes.
Notes from testing
These are the clues that make the staged app look like the problem:
- Fresh stock Discord bootstrap succeeds.
- Fresh bootstrap with OpenAsar injected before the first ShipIt handoff can loop.
- After one successful stock bootstrap, cleaning install files and injecting OpenAsar again can work.
- The expected final
/Applications/<channel app>.app replacement/relaunch may not happen when the staged app already contains OpenAsar.
- Trying to brute-force the metadata by replacing
app.asar with OpenAsar and patching the OpenAsar hash into installer.db did not solve the loop.
So far I have not found an in-process or metadata-only workaround. The only working approach I have found is outside the Discord process:
- Keep OpenAsar out of the staged
app-0.0.xxx/Discord.app.
- Store the OpenAsar payload somewhere in that channel's App Support folder.
- Start a small detached helper before calling Discord's native
UpdateMacOSHostVersion.
- Let ShipIt complete with the stock staged app.
- Have the helper wait for ShipIt to exit.
- Patch the final channel app's
Contents/Resources/app.asar with OpenAsar.
- Relaunch the final app.
The helper needs to be outside Discord because the Discord process exits during the host handoff. It also should not depend on Discord's Electron binary running JS as Node during this bootstrap window.
Suggested fix direction
OpenAsar should avoid injecting into the temporary staged app during macOS first-bootstrap / host handoff:
~/Library/Application Support/<channel data dir>/app-0.0.xxx/<channel app>.app
Instead, let Discord/ShipIt finish the stock handoff first, then restore OpenAsar into the final app under /Applications.
Summary
Recent Discord Stable macOS builds appear to have changed the cold-boot / first-bootstrap host-app handoff enough that OpenAsar's current macOS retention behavior can break fresh installs.
The short version: Discord now appears to require the ShipIt bootstrap handoff to clear with the stock staged app. If OpenAsar patches
app.asarinside the stagedapp-0.0.xxx/Discord.appbefore ShipIt finishes, Discord can loop or never reach the usable client.Observed on Discord Stable macOS
0.0.396. Other channels/builds may be affected if they use the same ShipIt handoff path.Reproduction shape
This is the failure pattern I can reproduce from a clean first-bootstrap state:
installer.dbShipIt_request.json0.0.xxx/app-0.0.xxx/modules/module_data/download/Cache/Code Cache/Contents/Resources/app.asarwith OpenAsar before Discord's first post-cleanup launch.app-0.0.xxx/Discord.app/Contents/Resources/app.asarThe same machine completes the flow if the first bootstrap is allowed to run with stock Discord first. After that stock handoff completes once, OpenAsar can be injected into the final app and Discord launches normally.
Expected behavior
Final app examples:
Actual behavior
With current upstream-style staged-app injection:
app-0.0.xxx/Discord.appbefore ShipIt finishes.ShipIt_request.jsoncan remain behind.This points more toward a staged-app ShipIt/bootstrap validation issue than a normal OpenAsar runtime issue. OpenAsar still works in the final app after a stock handoff completes.
Notes from testing
These are the clues that make the staged app look like the problem:
/Applications/<channel app>.appreplacement/relaunch may not happen when the staged app already contains OpenAsar.app.asarwith OpenAsar and patching the OpenAsar hash intoinstaller.dbdid not solve the loop.So far I have not found an in-process or metadata-only workaround. The only working approach I have found is outside the Discord process:
app-0.0.xxx/Discord.app.UpdateMacOSHostVersion.Contents/Resources/app.asarwith OpenAsar.The helper needs to be outside Discord because the Discord process exits during the host handoff. It also should not depend on Discord's Electron binary running JS as Node during this bootstrap window.
Suggested fix direction
OpenAsar should avoid injecting into the temporary staged app during macOS first-bootstrap / host handoff:
Instead, let Discord/ShipIt finish the stock handoff first, then restore OpenAsar into the final app under
/Applications.