microsoft/aspire · error · InvalidOperationException

AppHost path not found in configuration.

Error message

AppHost path not found in configuration.

What it means

GetAppHostInformationAsync reads the AppHost file path from configuration keys AppHost:FilePath (preferred) or AppHost:Path (fallback). When neither is set, it logs an error and throws this InvalidOperationException because the response cannot be built without a path.

Solutions

  1. Launch the AppHost through the Aspire CLI or AppHost runner, which sets AppHost:FilePath.
  2. Set configuration AppHost:FilePath (full path with extension) explicitly, e.g. env var AppHost__FilePath=/path/to/AppHost.csproj.
  3. Verify KnownConfigNames wiring — AppHost:Path is only a fallback; prefer FilePath.
  4. Check that config sources (appsettings, env vars) are actually loaded in the host process.

Example fix

// before
dotnet run --project MyApproj // config lacks AppHost:FilePath
// after
AppHost__FilePath=/path/to/MyApp.AppHost/MyApp.AppHost.csproj dotnet run --project MyApp.AppHost
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(configuration["AppHost:FilePath"]) && string.IsNullOrEmpty(configuration["AppHost:Path"]))
    throw new InvalidOperationException("Set AppHost:FilePath (e.g. env AppHost__FilePath) before calling get-apphost-information.");

Try / catch

try { await rpc.GetAppHostInformationAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("AppHost path not found")) { logger.LogError(ex, "Launch via aspire CLI or set AppHost__FilePath."); }

Prevention

When it happens

Trigger: Calling the auxiliary backchannel GetAppHostInformationAsync RPC in a host process whose configuration lacks AppHost:FilePath/AppHost:Path — e.g. AppHost launched by a custom runner instead of the Aspire CLI/DCP, or config keys removed/renamed.

Common situations: Launching the AppHost directly via `dotnet run` or a custom host without Aspire's launcher wiring; environment variable or appsettings omissions; mixing Aspire versions where the config key names changed.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/Backchannel/AuxiliaryBackchannelRpcTarget.cs:870

    #region V1 API Methods (Legacy - Keep for backward compatibility)

    /// <summary>
    /// Gets information about the AppHost for the MCP server.
    /// </summary>
    /// <param name="cancellationToken">A cancellation token.</param>
    /// <returns>The AppHost information including the fully qualified path and process ID.</returns>
    /// <exception cref="InvalidOperationException">Thrown when AppHost information is not available.</exception>
    public Task<AppHostInformation> GetAppHostInformationAsync(CancellationToken cancellationToken = default)
    {
        // The cancellationToken parameter is not currently used, but is retained for API consistency and potential future support for cancellation.
        _ = cancellationToken;

        // First try to get the file path (with extension), otherwise fall back to the path (without extension)
        var appHostPath = configuration["AppHost:FilePath"] ?? configuration["AppHost:Path"];
        if (string.IsNullOrEmpty(appHostPath))
        {
            logger.LogError("AppHost path not found in configuration.");
            throw new InvalidOperationException("AppHost path not found in configuration.");
        }

        // Get the CLI process ID if the AppHost was launched via the CLI
        int? cliProcessId = null;
        var cliPidString = configuration[KnownConfigNames.CliProcessId];
        if (!string.IsNullOrEmpty(cliPidString) && int.TryParse(cliPidString, out var parsedCliPid))
        {
            cliProcessId = parsedCliPid;
        }
        DateTimeOffset? cliStartedAt = null;
        var cliStartedAtString = configuration[KnownConfigNames.CliProcessStarted];
        if (!string.IsNullOrEmpty(cliStartedAtString) && long.TryParse(cliStartedAtString, out var parsedCliStartedAt))
        {
            cliStartedAt = DateTimeOffset.FromUnixTimeSeconds(parsedCliStartedAt);
        }

        // ASPIRE_CLI_STARTED_STABLE is the stable launcher-CLI identity time that current CLIs stamp
        // alongside the legacy value, in Unix milliseconds. It survives wall-clock steps, so surfacing it

View on GitHub (pinned to 25830f84bd)