Skip to content

Homebrew cask launcher asks for AZ_PYTHON when the Homebrew prefix is a symlink #34187

Description

@Naimor-HM

Describe the bug

With the new Homebrew cask (brew install --cask azure-cli, 2.91.0), az fails on a Mac where the Homebrew prefix is a symlink (here /opt/homebrew -> /private/.bulk/opt/homebrew, which itself resolves to another volume):

Error: AZ_PYTHON not set.
For offline/tarball installs, set AZ_PYTHON to a Python 3.14 path.

Cause: scripts/release/standalone/templates/az_launcher.sh.in resolves its own path with cd -P (physical), then compares the result against literal prefixes:

if [[ "$SCRIPT_PATH" == /opt/homebrew/Caskroom/* ]] || \
    [[ "$SCRIPT_PATH" == /usr/local/Caskroom/* ]] || \
    [[ "$SCRIPT_PATH" == /home/linuxbrew/.linuxbrew/Caskroom/* ]]; then

bash -x shows the resolved path is /Volumes/Data/.bulk/opt/homebrew/Caskroom/azure-cli/2.91.0/bin/../libexec/bin/az, so INSTALLER=TARBALL and the launcher demands AZ_PYTHON, even though it is a cask install and python@3.14 is installed. The same happens with any custom Homebrew prefix.

To reproduce

  1. Make the Homebrew prefix a symlink to another location (for example, a prefix relocated to a second volume).
  2. brew install --cask azure-cli
  3. az version

Expected behavior

The cask install is detected and uses Homebrew's python@3.14, with no AZ_PYTHON needed.

Suggestions

  • Detect a cask install by pattern rather than literal prefix, for example */Caskroom/azure-cli/*. Or compare against the physical path of $HOMEBREW_PREFIX, or brew --prefix.
  • Minor: the first candidate, opt/python@3.14/libexec/bin/python3, doesn't exist in Homebrew's python@3.14 (its libexec/bin has python, not python3). Detection only works because of the bin/python3.14 fallback.

Workaround

export AZ_PYTHON="$HOMEBREW_PREFIX/opt/python@3.14/bin/python3.14"

Environment

  • azure-cli 2.91.0, Homebrew cask (Homebrew 7.0.8), macOS 27 on Apple silicon
  • Homebrew prefix: /opt/homebrew, a symlink to /private/.bulk/opt/homebrew

Activity

  1. yonzhan commented on Oct 8, 2026

    @yonzhan
    Collaborator

    Thank you for opening this issue, we will look into it.

  2. x-engineering-agent commented on Oct 8, 2026

    @x-engineering-agent
    Contributor

    Bug Analysis

    Affected area: Homebrew cask / standalone packaging in Azure/azure-cli, target branch dev. Target inference found no command module or extension; this is repository-owned launcher code, not an extensions-repository issue.

    Use this EXACT PR title:

    [Packaging] Fix #34187: az version: Detect Homebrew casks with symlinked prefixes

    Reported reproduction and expected result

    Azure CLI 2.91.0 installed as a Homebrew cask, Homebrew 7.0.8, macOS 27 on Apple silicon. With the Homebrew prefix symlinked to a relocated directory, install the cask and invoke az version without AZ_PYTHON. The reporter observes Error: AZ_PYTHON not set. and the offline/tarball Python instruction, despite Homebrew python@3.14 being installed. The expected result is cask detection and use of the cask's Homebrew Python without requiring AZ_PYTHON.

    The issue supplies the exact command, error, expected behavior, versions and reproduction steps. No additional reporter information is blocking. Similar-issue lookup returned no candidates. This is source-supported analysis, not a locally executed reproduction.

    Current source evidence

    Inspected dev at fec1915074bb57bfcf40961fe0b982c1c96d7848:

    • templates/az_launcher.sh.in resolves launcher symlinks using physical directories, but classifies casks using three literal Homebrew prefixes. A resolved relocated prefix falls through to INSTALLER=TARBALL, which explains the reported AZ_PYTHON error.
    • The same launcher searches for Python only under those fixed prefixes. Broadening cask recognition alone is insufficient for a custom physical prefix: interpreter discovery must use the corresponding actual Homebrew installation too.
    • build_binary_tar_gz.py renders the launcher from that .in template in _create_launcher_script, uses Python version 3.14 by default and substitutes PYTHON_BIN=python3. Its build-time find_homebrew_python already uses the formula's libexec/bin/python candidate. The install structure creates bin/az as a relative link to ../libexec/bin/az.
    • templates/azure-cli.rb.in declares the versioned Homebrew Python formula dependency and installs bin/az as the cask binary.

    Requirements for the fix

    1. Fix cask recognition and Python discovery in the authoritative standalone launcher template for both symlinked standard prefixes and custom/relocated prefixes. Associate the interpreter with the detected Homebrew installation; do not select an unrelated installation or require an environment variable that ordinary cask invocation does not provide. Preserve quoting and macOS-compatible shell/path behavior.
    2. Keep the change scoped to launcher packaging and directly related regression coverage. Account for the formula's actual interpreter layout rather than relying solely on the nonexistent libexec/bin/python3 candidate; preserve working versioned-interpreter fallbacks.
    3. Preserve genuine offline/tarball behavior: outside a cask installation, require and honor explicit AZ_PYTHON, including existing missing/non-executable diagnostics. Preserve argument forwarding, AZ_INSTALLER, PYTHONPATH, package-location validation and supported standard-prefix behavior.
    4. Add focused regression coverage using repository test conventions and a rendered launcher. Cover a physically relocated prefix reached through symlinks, a custom prefix, the relative bin/az link, default-prefix behavior, versioned/formula Python lookup, missing Python, and non-cask execution with and without AZ_PYTHON. Include quoted paths with spaces. Use isolated fixtures, not mutations of a developer's Homebrew installation. In the implementation job, run the applicable existing validation and report actual results; do not claim macOS or live validation that was not performed.
    5. Edit the source template, not a generated release launcher, tarball or generated cask artifact. build_binary_tar_gz.py is the verified renderer; use the real renderer for coverage where appropriate. No AAZ-generated command code is involved or needs modification. Do not expand the fix into AAZ output. If an AAZ dependency is discovered, report the blocker and require the governed durable Azure/aaz source-PR/generation workflow rather than directly editing generated files.

    PR title & description format (required)

    This repo enforces a PR format (guide). Please author the PR exactly as follows or CI's Check the Format of Pull Request Title and Content will fail.

    Use this EXACT PR title (copy verbatim, do not reword):

    [Packaging] Fix #34187: `az version`: Detect Homebrew casks with symlinked prefixes
    

    Keep the backticks around the command and the Fix #34187: prefix. You may only adjust the wording after the command (the final summary) if the fix changes; the [Packaging] prefix, issue link, and backticked command must stay.

    Description — follow the PR template and fill in:

    • Link the issue — start the Description with a closing keyword so the PR auto-links and closes it: Fixes #34187.
    • Related command — the az ... command this affects.
    • Description (mandatory) — why the bug happens, what you changed, and the resulting behavior.
    • Testing Guide — example command(s) showing the fix works.
    • History Notes — leave the title to drive the history note, or add extra lines in the same format (component in brackets + the command in backticks), e.g. [Packaging] `az <command>`: <note>.
    • Keep the template checklist and tick the items you've satisfied.

    Posted by x-engineering-agent (Fixer)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Azure CLI TeamThe command of the issue is owned by Azure CLI teamcustomer-reportedIssues that are reported by GitHub users external to the Azure organization.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions