Summary
When running aspire run (or aspire restore) from a parent directory of the AppHost, the CLI fails to discover an existing aspire.config.json that lives next to the AppHost file in a subdirectory. Instead, it creates a new incomplete aspire.config.json at the CWD, which then causes the AppHost server to fail.
Root Cause
There is an asymmetry in how the CLI discovers the AppHost file vs. the config file:
- AppHost discovery (
ProjectLocator): Scans downward into subdirectories from CWD → successfully finds src/apphost.ts
- Config discovery (
ConfigurationService.FindNearestSettingsFile()): Searches upward from CWD → never finds src/aspire.config.json
When the config isn't found, GetOrCreateLocalAspireConfigFile() (ProjectLocator.cs L448) creates a new aspire.config.json at CWD:
// ProjectLocator.cs, line 448
var newConfigPath = Path.Combine(executionContext.WorkingDirectory.FullName, AspireConfigFile.FileName);
This new config only has appHost.path set (e.g. "src/apphost.ts") but is missing all the user's packages, profiles, channel, and other settings — causing the AppHost server to fail.
Meanwhile, ConfigurationService.FindNearestSettingsFile() (ConfigurationService.cs L93-125) only walks upward:
private string FindNearestSettingsFile()
{
var searchDirectory = executionContext.WorkingDirectory;
while (searchDirectory is not null)
{
var newSettingsPath = Path.Combine(searchDirectory.FullName, AspireConfigFile.FileName);
if (File.Exists(newSettingsPath))
return newSettingsPath;
searchDirectory = searchDirectory.Parent; // Only searches UP
}
// Falls back to CWD
return Path.Combine(executionContext.WorkingDirectory.FullName, AspireConfigFile.FileName);
}
Reproduction
-
Create a polyglot TypeScript AppHost in a subdirectory:
my-repo/
├── src/
│ ├── apphost.ts
│ └── aspire.config.json ← has packages, profiles, channel, etc.
└── (no aspire.config.json at root)
-
Run from the repo root:
-
Expected: CLI finds src/apphost.ts and uses src/aspire.config.json alongside it.
-
Actual:
🔍 Finding apphosts...
src\apphost.ts
🗄 Created settings file at 'aspire.config.json'. ← creates incomplete config at root
❌ Failed to run TypeScript (Node.js) AppHost: Failed to authenticate to the AppHost server.
Log output confirming the issue
[INFO] [ConfigurationService] Found settings file at C:\Users\...\my-repo\aspire.config.json
[INFO] [GuestAppHostProject] Loaded config from C:\Users\...\my-repo (file exists: True)
[FAIL] [GuestAppHostProject] Failed to run TypeScript (Node.js) AppHost
System.InvalidOperationException: Failed to authenticate to the AppHost server.
The log shows it found/created the config at the repo root rather than using the existing one in src/.
Suggested fix
When the CLI discovers an AppHost file via subdirectory scanning, it should also check for aspire.config.json in the AppHost's directory (and its parent chain up to CWD) before falling back to creating a new one at CWD.
Possible approaches:
- After discovering the AppHost at
src/apphost.ts, check src/aspire.config.json first
- Make
FindNearestSettingsFile() accept an optional anchor directory (the AppHost's directory) instead of always starting from CWD
- In
CreateSettingsFileAsync, if a config already exists adjacent to the discovered AppHost, use that instead of creating a new one
Workaround
Run aspire run from the directory containing both apphost.ts and aspire.config.json:
Summary
When running
aspire run(oraspire restore) from a parent directory of the AppHost, the CLI fails to discover an existingaspire.config.jsonthat lives next to the AppHost file in a subdirectory. Instead, it creates a new incompleteaspire.config.jsonat the CWD, which then causes the AppHost server to fail.Root Cause
There is an asymmetry in how the CLI discovers the AppHost file vs. the config file:
ProjectLocator): Scans downward into subdirectories from CWD → successfully findssrc/apphost.tsConfigurationService.FindNearestSettingsFile()): Searches upward from CWD → never findssrc/aspire.config.jsonWhen the config isn't found,
GetOrCreateLocalAspireConfigFile()(ProjectLocator.cs L448) creates a newaspire.config.jsonat CWD:This new config only has
appHost.pathset (e.g."src/apphost.ts") but is missing all the user's packages, profiles, channel, and other settings — causing the AppHost server to fail.Meanwhile,
ConfigurationService.FindNearestSettingsFile()(ConfigurationService.cs L93-125) only walks upward:Reproduction
Create a polyglot TypeScript AppHost in a subdirectory:
Run from the repo root:
cd my-repo aspire runExpected: CLI finds
src/apphost.tsand usessrc/aspire.config.jsonalongside it.Actual:
Log output confirming the issue
The log shows it found/created the config at the repo root rather than using the existing one in
src/.Suggested fix
When the CLI discovers an AppHost file via subdirectory scanning, it should also check for
aspire.config.jsonin the AppHost's directory (and its parent chain up to CWD) before falling back to creating a new one at CWD.Possible approaches:
src/apphost.ts, checksrc/aspire.config.jsonfirstFindNearestSettingsFile()accept an optional anchor directory (the AppHost's directory) instead of always starting from CWDCreateSettingsFileAsync, if a config already exists adjacent to the discovered AppHost, use that instead of creating a new oneWorkaround
Run
aspire runfrom the directory containing bothapphost.tsandaspire.config.json:cd src aspire run