Skip to content

bundle: try mas install before falling back to mas get#22271

Merged
MikeMcQuaid merged 1 commit into
Homebrew:masterfrom
wojteksbt:mas-install-fallback
May 14, 2026
Merged

bundle: try mas install before falling back to mas get#22271
MikeMcQuaid merged 1 commit into
Homebrew:masterfrom
wojteksbt:mas-install-fallback

Conversation

@wojteksbt
Copy link
Copy Markdown
Contributor

@wojteksbt wojteksbt commented May 13, 2026


  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them? Performance claims (e.g. "this is faster") must include Hyperfine benchmarks.
  • Have you written new tests (excluding integration tests) for your changes? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) with your changes locally?

(Ran components individually: brew tests --only=bundle/mac_app_store --no-parallel 14/14 pass, brew style no new offenses, brew typecheck clean.)


  • AI was used to generate or assist with generating this PR. Please specify below how you used AI to help you, and what steps you have taken to manually verify the changes. Non-maintainers may only have one AI-assisted/generated PR open at a time.

AI (Claude Code) drafted the patch and RSpec test based on issue #22270, which I authored after manually reproducing the regression on a fresh macOS 26.5 install. I verified the empirical reproducer myself (mas get <id> fails where mas install <id> succeeds for a purchase-history app not on disk). Tests, style, and typecheck were all run locally before pushing.


What this fixes

Fixes #22270.

PR #21590 switched brew bundle from mas install to mas get based on the assertion in #21559 that they're equivalent for already-purchased apps. Empirically on macOS 26.5 / mas 7.0.0 this isn't true — mas get returns No downloads initiated for ADAM ID <id> for apps in the Apple ID's purchase history but not present on disk, while mas install succeeds for the same id in the same session.

This adopts the fallback strategy from the #21559 body that wasn't taken in #21590:

Try mas install first (fast path for already-associated apps). Fall back to mas get if install fails with the redownload error.

Both scenarios are now covered: purchase-history restore (install succeeds, get not called) and fresh Apple Account (install fails, get takes over).

cc @rgoldberg @MikeMcQuaid

@github-actions
Copy link
Copy Markdown

Thanks for your pull request. This has been closed because it appears to use an incomplete or outdated pull request template.

Please edit the pull request body to fill in the current pull request template. This workflow will reopen the pull request automatically once the template is complete.

@github-actions github-actions Bot closed this May 13, 2026
@github-actions github-actions Bot reopened this May 13, 2026
@rgoldberg
Copy link
Copy Markdown
Contributor

rgoldberg commented May 13, 2026

mas get installs previously gotten, but not currently installed apps just fine for me on macOS 26.5 & mas 7.0.0.

I need to investigate.

Fixes purchase-history regression introduced by Homebrew#21590 (closes Homebrew#21559).
`mas get` fails on macOS 26.5 / mas 7.0.0 for apps in the Apple ID's
purchase history but not on disk, while `mas install` succeeds.
Try `install` first (fast path for owned apps); fall back to `get`
for fresh-account scenario (the original Homebrew#21559 motivation).

Fixes Homebrew#22270
@wojteksbt wojteksbt force-pushed the mas-install-fallback branch from 15854df to a67c0f2 Compare May 13, 2026 20:26
@rgoldberg
Copy link
Copy Markdown
Contributor

rgoldberg commented May 13, 2026

I've never gotten 1160374471 before. I had never even heard of it, so my first get below is the first time my account got it. I don't know why @wojteksbt is experiencing different behavior.

$ mas config
mas ▁▁▁▁ 7.0.0
slice ▁▁ arm64
slices ▁ arm64
dist ▁▁▁ homebrew/core/mas
origin ▁ https://github.com/mas-cli/mas.git
rev ▁▁▁▁ 7c70ffdfd9f71a654300a78b3b627782e6abe1b4
swift ▁▁ 6.3 (swiftlang-6.3.0.123.5 clang-2100.0.123.102)
driver ▁ 1.148.6
store ▁▁ US
region ▁ US
macos ▁▁ 26.5 (25F71)
mac ▁▁▁▁ Mac16,9
cpu ▁▁▁▁ Apple M4 Max
arch ▁▁▁ arm64

$ mas get 1160374471
Password:
==> Downloading PiPifier (1.4)
==> Downloaded PiPifier (1.4)
==> Getting PiPifier (1.4)
==> Got PiPifier (1.4) in /Applications/PiPifier.app

$ mas list 1160374471
1160374471  PiPifier  (1.4)

$ mas uninstall 1160374471
Uninstalled '/Applications/PiPifier.app' to '/Users/user/.Trash/PiPifier.app'

$ mas list 1160374471     
Error: No installed apps with ADAM ID 1160374471
Warning: No installed apps found

         If this is unexpected, index apps in Spotlight (which might take some time):

         # Individual app (if the omitted apps are known). e.g., for Xcode:
         mdimport /Applications/Xcode.app

         # All apps:
         vol="$(/usr/libexec/PlistBuddy -c "Print :PreferredVolume:name" ~/Library/Preferences/com.apple.appstored.plist 2>/dev/null)"
         mdimport /Applications ${vol:+"/Volumes/${vol}/Applications"}

         # All volumes:
         sudo mdutil -Eai on

$ mas get 1160374471     
==> Downloading PiPifier (1.4)
==> Downloaded PiPifier (1.4)
==> Getting PiPifier (1.4)
==> Got PiPifier (1.4) in /Applications/PiPifier.app

$ mas list 1160374471
1160374471  PiPifier  (1.4)

@wojteksbt
Copy link
Copy Markdown
Contributor Author

Thanks for the quick turnaround on this.

Context: I use brew bundle to bootstrap a fresh macOS install, so every mas line in my Brewfile is an app purchased long ago on a different machine, never touched locally on this one. That's the scenario the PR addresses. Machine is vanilla — no third-party tweaks, no custom defaults — about as standard a setup as it gets.

My config (differs from yours only in store/region):

mas    7.0.0
rev    7c70ffdfd9f71a654300a78b3b627782e6abe1b4
store  PL
region PL
macos  26.5 (25F71)
mac    MacBookAir10,1 / Apple M1
arch   arm64

Reproducer with Hush (1544743900) — uninstall + mas get in the same session, matching the shape of your test:

$ mas list 1544743900
1544743900  Hush  (1.0.18)

$ mas uninstall 1544743900
Uninstalled '/Applications/Hush.app' to '/Users/wojtek/.Trash/Hush.app'

$ mas list 1544743900
Error: No installed apps with ADAM ID 1544743900
Warning: No installed apps found

$ mas get 1544743900
Error: No downloads initiated for ADAM ID 1544743900

$ mas install 1544743900
==> Downloading Hush Nag Blocker (1.0.18)
==> Downloaded Hush Nag Blocker (1.0.18)
==> Installing Hush Nag Blocker (1.0.18)
==> Installed Hush Nag Blocker (1.0.18) in /Applications/Hush.app

One nuance: even your passing test (getuninstallget) exercises "acquired this session, then re-fetched", which has fresher appstoreagent / storedownloadd state than the real bootstrap case (account hasn't touched the app on this machine in years). My Hush repro above is the apples-to-apples version of your test and still fails — so the delta isn't "session-fresh vs old purchase".

No hypothesis yet on the root cause. Happy to capture log stream during the failing mas get if useful.

@rgoldberg
Copy link
Copy Markdown
Contributor

Thanks for the additional detail. If you can provide the log stream from a failure in a bug report in the mas repo, that would be useful. Unfortunately, I probably won't be able to investigate much now, but it would be useful to have it documented for future investigation.

Homebrew personnel: if & when this is solved, or more information is found about the extent and/or cause of the different behaviors, I'll let you know.

I could create a new mas command, or update one of the existing commands, to try get then install if the get fails (or vice versa), but I assume that running one command then the other, like in this PR, should solve the problem for brew bundle.

Copy link
Copy Markdown
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

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

Makes sense, thanks @wojteksbt!

@MikeMcQuaid MikeMcQuaid merged commit d676fcd into Homebrew:master May 14, 2026
34 of 35 checks passed
@wojteksbt
Copy link
Copy Markdown
Contributor Author

Hi @rgoldberg, I filed the upstream issue with the log stream evidence: mas-cli/mas#1253. Thank you and @MikeMcQuaid for the help and the lightning-fast responses.

@wojteksbt
Copy link
Copy Markdown
Contributor Author

wojteksbt commented May 18, 2026

Hi @MikeMcQuaid — quick note: this PR was opened against master instead of main (my fork's default branch was stale, so GitHub defaulted the upstream base to master). I just tried to switch the base to main but GitHub blocks that on closed/merged PRs.

Looking at the post-merge runs on d676fcde, the rollback appears to have been triggered by the Sync default branches workflow:

remote: - Changes must be made through the merge queue
 ! [remote rejected] d676fcde98f646802a6e23d23c1aabd81beec60f -> main (push declined due to repository rule violations)

— the direct merge into master couldn't be force-pushed to main because of the merge-queue protection rule. The one tests (macOS) failure on the same commit (pkg-config returns the correct version for expat, 2.7.4 vs 2.7.3) was unrelated flaky bottle cache, nothing this PR touches.

If you'd still like this change, I'm happy to open a fresh PR with base=main so it can go through the merge queue cleanly. Sorry for the noise!

@MikeMcQuaid
Copy link
Copy Markdown
Member

If you'd still like this change, I'm happy to open a fresh PR with base=main so it can go through the merge queue cleanly. Sorry for the noise!

Please, thanks!

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.

3 participants