microsoft / microsoft/aspire

AppHost fails to start unless all profiles are "correct"

Open
#8,795 3 comments 0 reactions 0 assignees View on GitHub
needs-retriage
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

When running Aspire AppHost, the process validates **all** profiles in launchSettings.json, even the extra ones defined for custom dev tasks.

Given the following `launchSettings.json`

```json
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:60000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:60001;http://localhost:60000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"debug": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:60001;http://localhost:60000",
"environmentVariables": {
"FOO": 123
}
}
}
}
```

where the "debug" profile has a minor issue - "FOO" should be a string not a number - Aspire AppHost fails to start and throws an exception:

> Unhandled exception. Aspire.Hosting.DistributedApplicationException: **Failed to get effective launch profile** for project resource 'MyProject'. There is **malformed JSON** in the project's launch settings file at 'MyProject/Properties/launchSettings.json'
> ---> System.Text.Json.JsonException: **The JSON value could not be converted to System.String**. Path: $.profiles.debug.environmentVariables.FOO | LineNumber: 27 | BytePositionInLine: 20.
> ---> System.InvalidOperationException: **Cannot get the value of a token type 'Number' as a string**.
> at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_ExpectedString(JsonTokenType tokenType)
> at System.Text.Json.Utf8JsonReader.GetString()
> at System.Text.Json.Serialization.Converters.StringConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
> at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
> at System.Text.Json.Serialization.JsonDictionaryConverter`3.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TDictionary& value)
> at System.Text.Json.Serialization.Converters.JsonMetadataServicesConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
> at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
> at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
> at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
> at System.Text.Json.Serialization.Converters.JsonMetadataServicesConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
> at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
> at System.Text.Json.Serialization.JsonDictionaryConverter`3.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TDictionary& value)
> at System.Text.Json.Serialization.Converters.JsonMetadataServicesConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
> at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
> at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
> at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
> at System.Text.Json.Serialization.Converters.JsonMetadataServicesConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
> at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
> at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
> --- End of inner exception stack trace ---
> at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, Utf8JsonReader& reader, Exception ex)
> at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
> at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.ContinueDeserialize(ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, T& value)
> at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Deserialize(Stream utf8Json)
> at System.Text.Json.JsonSerializer.Deserialize[TValue](Stream utf8Json, JsonTypeInfo`1 jsonTypeInfo)
> at Aspire.Hosting.LaunchProfileExtensions.GetLaunchSettings(IProjectMetadata projectMetadata, String resourceName) in /_/src/Shared/LaunchProfiles/LaunchProfileExtensions.cs:line 97
> --- End of inner exception stack trace ---
> at Aspire.Hosting.LaunchProfileExtensions.GetLaunchSettings(IProjectMetadata projectMetadata, String resourceName) in /_/src/Shared/LaunchProfiles/LaunchProfileExtensions.cs:line 103
> at Aspire.Hosting.LaunchProfileExtensions.GetLaunchSettings(ProjectResource projectResource) in /_/src/Shared/LaunchProfiles/LaunchProfileExtensions.cs:line 28
> at Aspire.Hosting.LaunchProfileExtensions.TrySelectLaunchProfileFromDefaultAnnotation(ProjectResource projectResource, String& launchProfileName) in /_/src/Shared/LaunchProfiles/LaunchProfileExtensions.cs:line 138
> at Aspire.Hosting.LaunchProfileExtensions.SelectLaunchProfileName(ProjectResource projectResource) in /_/src/Shared/LaunchProfiles/LaunchProfileExtensions.cs:line 179
> at Aspire.Hosting.LaunchProfileExtensions.GetEffectiveLaunchProfile(ProjectResource projectResource, Boolean throwIfNotFound) in /_/src/Shared/LaunchProfiles/LaunchProfileExtensions.cs:line 33
> at Aspire.Hosting.ProjectResourceBuilderExtensions.WithProjectDefaults(IResourceBuilder`1 builder, ProjectResourceOptions options) in /_/src/Aspire.Hosting/ProjectResourceBuilderExtensions.cs:line 341
> at Aspire.Hosting.ProjectResourceBuilderExtensions.AddProject(IDistributedApplicationBuilder builder, String name, String projectPath, Action`1 configure) in /_/src/Aspire.Hosting/ProjectResourceBuilderExtensions.cs:line 282
> at Aspire.Hosting.ProjectResourceBuilderExtensions.AddProject(IDistributedApplicationBuilder builder, String name, String projectPath) in /_/src/Aspire.Hosting/ProjectResourceBuilderExtensions.cs:line 100

### Expected Behavior

While the error is ok-ish, there is no reason to validate every profile in launchSettings.json, is there? It seems a waste of resources, and AppHost should just start if the profile selected is fine, ignoring other profiles.

Outside the scope of this issue: the env var parser could be improved, just taking the number as a string, like bash vars and .env files work.

### Steps To Reproduce

Add a profile with an env var where the value is a number.

### .NET Version info

.NET 9
Aspire 9.1

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.