Skip to content

Fix brew outdated --greedy crash on installed casks without a URL#23084

Merged
MikeMcQuaid merged 1 commit into
mainfrom
cask-outdated-empty-url
Jul 13, 2026
Merged

Fix brew outdated --greedy crash on installed casks without a URL#23084
MikeMcQuaid merged 1 commit into
mainfrom
cask-outdated-empty-url

Conversation

@p-linnane

Copy link
Copy Markdown
Contributor

After installed cask metadata migration was enabled for all users, brew outdated --greedy began failing with Error: attempted to use a Downloadable without a URL! on :latest casks whose minimal installed JSON omits url (reported in https://github.com/orgs/Homebrew/discussions/6961).

CaskStructGenerator built url_args as [hash["url"].to_s], so an absent url became [""]. That one-element array is not blank, so it survived compact_blank and reached url("") in the loader. Since "" is truthy, the DSL wrapped it in a real URL instead of leaving the url unset, making checksumable? true and sending greedy outdated detection into the downloader.

Calling compact_blank on the array drops the blank element, so an absent url yields no arguments, cask.url is nil, and checksumable? returns false. Such :latest casks are still reported outdated under --greedy, now without touching the downloader. This matches the internal API round-trip, which already strips blank url_args on serialization.

The regression test reconstructs URL-less installed :latest metadata with an existing LATEST_DOWNLOAD_SHA256 and asserts the greedy check returns instead of raising.


  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include Hyperfine benchmarks.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • AI was used to generate or assist with generating this PR.

Claude Code (Opus 4.8) diagnosed the empty-URL path and wrote the fix and regression test; I reviewed the diff and verified with brew lgtm plus targeted cask/cask_loader/from_api_loader, api/cask_struct, and api/cask/cask_struct_generator specs.


Copilot AI review requested due to automatic review settings July 13, 2026 16:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a regression where brew outdated --greedy could crash for installed :latest casks whose migrated installed JSON metadata omits url, by ensuring API cask struct generation does not produce a blank url("") stanza.

Changes:

  • Drop blank url values when generating url_args for cask structs, so URL-less installed metadata yields cask.url == nil.
  • Add a regression spec that reconstructs URL-less installed :latest metadata with an existing LATEST_DOWNLOAD_SHA256 and asserts greedy outdated detection returns without raising.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
Library/Homebrew/api/cask/cask_struct_generator.rb Ensures missing url does not become [""], preventing url("") from being set in the loader path.
Library/Homebrew/test/cask/cask_loader/from_api_loader_spec.rb Adds coverage for the URL-less installed-metadata scenario that previously triggered the downloader crash under --greedy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@MikeMcQuaid MikeMcQuaid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

Signed-off-by: Patrick Linnane <patrick@linnane.io>
@p-linnane p-linnane force-pushed the cask-outdated-empty-url branch from cede219 to 41cdb6e Compare July 13, 2026 23:04
@MikeMcQuaid MikeMcQuaid added this pull request to the merge queue Jul 13, 2026
Merged via the queue into main with commit 5b7ab28 Jul 13, 2026
41 checks passed
@MikeMcQuaid MikeMcQuaid deleted the cask-outdated-empty-url branch July 13, 2026 23:42
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