microsoft/aspire · error · AzureCliNotOnPathException

AzureCliNotOnPathException (Azure CLI is not on PATH)

Error message

AzureCliNotOnPathException (Azure CLI is not on PATH)

What it means

BicepCompiler.CompileBicepToArmAsync first tries a standalone `bicep` CLI; if absent it falls back to `az bicep build`. If neither is found (PathLookupHelper can't locate `az` on PATH) it throws AzureCliNotOnPathException, indicating the Azure CLI is required to compile the bicep file to ARM.

Solutions

  1. Install the Azure CLI (`az`) and ensure it is on PATH (`az --version` works in the same shell that runs the AppHost).
  2. Alternatively install the standalone Bicep CLI (`bicep --version`) so the az fallback is not needed.
  3. In CI, use an image/step that includes the Azure CLI (e.g. Azure/cli@v2 action or microsoft/azure-cli image).
  4. Fix PATH so the install location of az (e.g. ~/.local/bin or /usr/local/bin) is included.

Example fix

// before
# az: command not found
// after
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash && az --version
Defensive patterns

Strategy: validation

Validate before calling

if (IsWindows)
    CheckOnPath("az.cmd");
else
    CheckOnPath("az");

static void CheckOnPath(string tool)
{
    var pathEnv = Environment.GetEnvironmentVariable("PATH") ?? "";
    // simplest precheck: try spawning `<tool> --version` and treat failure as not-installed
}

Try / catch

try { await compiler.CompileBicepToArmAsync(bicepPath); }
catch (AzureCliNotOnPathException) { /* install Azure CLI or Bicep CLI, fix PATH, retry */ }

Prevention

When it happens

Trigger: Provisioning a bicep-based resource on a machine without the Azure CLI (`az`) on PATH and without the standalone Bicep CLI installed — e.g. slim CI containers or fresh dev machines.

Common situations: Docker images with only the .NET SDK; CI runners where PATH lacks /usr/bin/az; Azure CLI installed via a non-PATH location; Windows installs where az.exe isn't on the user PATH.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/1a5e579c12bdd7fc. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Azure/Provisioning/Internal/BicepCompiler.cs:41

    public async Task<string> CompileBicepToArmAsync(string bicepFilePath, CancellationToken cancellationToken = default)
    {
        // Try bicep command first for better performance
        var bicepPath = PathLookupHelper.FindFullPathFromPath("bicep");
        string commandPath;
        string arguments;

        if (bicepPath is not null)
        {
            commandPath = bicepPath;
            arguments = $"build \"{bicepFilePath}\" --stdout";
        }
        else
        {
            // Fall back to az bicep if bicep command is not available
            var azPath = PathLookupHelper.FindFullPathFromPath("az");
            if (azPath is null)
            {
                throw new AzureCliNotOnPathException();
            }
            commandPath = azPath;
            arguments = $"bicep build --file \"{bicepFilePath}\" --stdout";
        }

        var armTemplateContents = new StringBuilder();
        var errorContents = new StringBuilder();
        var templateSpec = new ProcessSpec(commandPath)
        {
            Arguments = arguments,
            OnOutputData = data =>
            {
                _logger.LogDebug("{CommandPath} (stdout): {Output}", commandPath, data);
                armTemplateContents.AppendLine(data);
            },
            OnErrorData = data =>
            {
                _logger.LogDebug("{CommandPath} (stderr): {Error}", commandPath, data);

View on GitHub (pinned to 25830f84bd)