microsoft/aspire · error · InvalidOperationException
The 'rad' CLI was not found. Please install it from
Error message
The 'rad' CLI was not found. Please install it from {RadInstallUrl} and ensure it is available on your PATH. What it means
RadiusCredentialRegisterStep (RadCredentialRegisterStep) registers credentials needed for Radius deployment by invoking the 'rad' CLI. Before doing so it runs DetectRadCliAsync; if rad is not on PATH it logs and throws this exception directing the user to install rad from the documented URL. Without the rad binary, credential registration and any subsequent Radius deployment cannot proceed.
Solutions
- Install the rad CLI per https://radapp.io (e.g., curl -fsSL https://get.radapp.dev/install.sh | bash) and verify with 'rad version'
- Ensure the rad binary's directory is on PATH for the process running the Aspire publish/deploy (export PATH="$PATH:/usr/local/bin" or equivalent in CI)
- Pin/install rad as a CI setup step before running aspire publish/deploy
- Use a container or runner image that already includes the rad CLI
Example fix
// before: CI job deploys without rad installed steps: - run: aspire publish -o artifacts // after: install rad first and expose it on PATH steps: - run: curl -fsSL https://get.radapp.dev/install.sh | bash - run: rad version - run: aspire publish -o artifacts
Defensive patterns
Strategy: validation
Validate before calling
# Fail fast before deploying if rad is missing
command -v rad >/dev/null 2>&1 || { echo "rad CLI not found; install from https://radapp.io"; exit 1; }
rad version Try / catch
try
{
await step.ExecuteAsync(context, ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("'rad' CLI was not found"))
{
// Surface a setup failure, not a deploy failure: install rad and retry.
logger.LogError("Install the rad CLI (https://radapp.io) and ensure it is on PATH, then retry.");
throw;
} Prevention
- Install rad as an explicit CI setup step and verify with 'rad version'
- Bake rad into runner/container images used for deploys
- Check PATH propagation when invoking deploys from IDEs or wrappers
When it happens
Trigger: Executing the Radius credential-register pipeline step (ExecuteAsync) on a machine where the 'rad' executable is not installed or not on the PATH environment variable used by the publish/deploy process.
Common situations: Fresh CI agent or dev container without Radius tooling installed; rad installed in a user path not visible to the CI process; typo'd or missing PATH configuration; using a container image without rad; forgetting to run the Radius install script (curl -fsSL https://radius.dev/install.sh | bash) before deploying.
Related errors
- The 'rad' CLI was not found. Please install it from
- Azure CLI (az) not found. Install it from…
- AzureCliNotOnPathException (Azure CLI is not on PATH)
- rad credential register failed with exit code
- A recipe parameter on Radius environment
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/fae1b1433bca3c96.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Radius/Publishing/RadCredentialRegisterStep.cs:96
var entries = BuildEntries(annotation).ToList();
if (entries.Count == 0)
{
return;
}
// Radius cloud-provider credentials are stored per-installation (global), not
// per-environment — registering one overwrites any previously registered
// credential for the same provider across ALL environments. Fail fast when the
// model configures conflicting credentials so the clobber surfaces as a clear
// error instead of a silent last-writer-wins surprise at deploy time.
// See https://docs.radapp.io/reference/cli/rad_credential_register/
ValidateNoConflictingInstallationCredentials(context.Model);
var radAvailable = await RadiusDeploymentPipelineStep.DetectRadCliAsync(cancellationToken).ConfigureAwait(false);
if (!radAvailable)
{
logger.LogError("The 'rad' CLI was not found on PATH. Install it from {InstallUrl}", RadiusDeploymentPipelineStep.RadInstallUrl);
throw RadiusDeploymentPipelineStep.CreateRadCliNotFoundException();
}
foreach (var entry in entries)
{
var args = await entry.ResolveArgumentsAsync(cancellationToken).ConfigureAwait(false);
await RunRadAsync(args, entry.SecretArgFlagSet, logger, cancellationToken).ConfigureAwait(false);
}
}
// The 'rad credential register' grammar uses TWO positional tokens — provider
// then auth-mode — and has NO '--name' flag (credentials are per-provider,
// per-installation). For example:
// rad credential register azure sp --client-id <id> --client-secret <secret> --tenant-id <tenant>
// rad credential register azure wi --client-id <id> --tenant-id <tenant>
// rad credential register aws access-key --access-key-id <id> --secret-access-key <secret>
// rad credential register aws irsa --iam-role <roleArn>
// See https://docs.radapp.io/reference/cli/rad_credential_register/ and its subcommands.
internal static IEnumerable<CredentialEntry> BuildEntries(View on GitHub (pinned to 25830f84bd)