Description
When aspire new creates a project in a subdirectory (e.g., ./MyProject/), two aspire.config.json files end up on disk:
- Root config (
./aspire.config.json): Created by ProjectLocator.CreateSettingsFileAsync — has appHost.path but no packages section
- Project config (
./MyProject/aspire.config.json): Created by the template — has the packages section with integration references
When subsequently running aspire run (or during the BuildAndGenerateSdkAsync step of aspire new itself), ConfigurationService.FindNearestSettingsFile walks up from the CWD and finds the root config first. Since the root config has no packages, the NuGet restore only gets Aspire.Hosting core — no integration assemblies are loaded, and the generated TypeScript SDK is missing all integration-specific functions (e.g., addUvicornApp, addViteApp).
Steps to Reproduce
mkdir workspace && cd workspace
aspire new → select "Starter App (FastAPI/React)" → name it MyApp
aspire run (from workspace/, NOT from workspace/MyApp/)
- Observe:
builder.addUvicornApp is not a function
Expected Behavior
Running aspire run from the workspace root should resolve packages from the project-level aspire.config.json (which contains the packages section), not the root config.
Workaround
cd MyApp before running aspire run / aspire start. This makes the config resolution find the correct project-level config.
Root Cause
ProjectLocator.CreateSettingsFileAsync writes appHost.path to a root-level aspire.config.json via ConfigurationService.SetConfigurationAsync("appHost.path", ...) but does not copy the packages section from the project config.
GuestAppHostProject.GetConfigDirectory uses _configurationService.GetSettingsFilePath(isGlobal: false) which calls FindNearestSettingsFile — this searches from CWD upward, finding the root config before the project config.
- The root config is authoritative for package resolution, but it has no packages.
Affected Scenarios
- Any TypeScript AppHost template with integration packages (
py-starter, ts-starter, etc.) when aspire run is invoked from a parent directory
- The
ts-starter E2E test works around this by cd-ing into the project directory before running
Possible Fixes
ProjectLocator.CreateSettingsFileAsync should copy/merge the packages section from the project config into the root config
- Or
GuestAppHostProject should resolve packages from the config nearest to the apphost file, not from CWD
- Or
aspire run should prefer the project-level config when the root config has no packages but points to a subdirectory that does
Description
When
aspire newcreates a project in a subdirectory (e.g.,./MyProject/), twoaspire.config.jsonfiles end up on disk:./aspire.config.json): Created byProjectLocator.CreateSettingsFileAsync— hasappHost.pathbut nopackagessection./MyProject/aspire.config.json): Created by the template — has thepackagessection with integration referencesWhen subsequently running
aspire run(or during theBuildAndGenerateSdkAsyncstep ofaspire newitself),ConfigurationService.FindNearestSettingsFilewalks up from the CWD and finds the root config first. Since the root config has no packages, the NuGet restore only getsAspire.Hostingcore — no integration assemblies are loaded, and the generated TypeScript SDK is missing all integration-specific functions (e.g.,addUvicornApp,addViteApp).Steps to Reproduce
mkdir workspace && cd workspaceaspire new→ select "Starter App (FastAPI/React)" → name itMyAppaspire run(fromworkspace/, NOT fromworkspace/MyApp/)builder.addUvicornApp is not a functionExpected Behavior
Running
aspire runfrom the workspace root should resolve packages from the project-levelaspire.config.json(which contains thepackagessection), not the root config.Workaround
cd MyAppbefore runningaspire run/aspire start. This makes the config resolution find the correct project-level config.Root Cause
ProjectLocator.CreateSettingsFileAsyncwritesappHost.pathto a root-levelaspire.config.jsonviaConfigurationService.SetConfigurationAsync("appHost.path", ...)but does not copy thepackagessection from the project config.GuestAppHostProject.GetConfigDirectoryuses_configurationService.GetSettingsFilePath(isGlobal: false)which callsFindNearestSettingsFile— this searches from CWD upward, finding the root config before the project config.Affected Scenarios
py-starter,ts-starter, etc.) whenaspire runis invoked from a parent directoryts-starterE2E test works around this bycd-ing into the project directory before runningPossible Fixes
ProjectLocator.CreateSettingsFileAsyncshould copy/merge thepackagessection from the project config into the root configGuestAppHostProjectshould resolve packages from the config nearest to the apphost file, not from CWDaspire runshould prefer the project-level config when the root config has no packages but points to a subdirectory that does