Description
Is there an existing issue for this?
- 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
{
"$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.JsonConverter1.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.JsonMetadataServicesConverter1.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.JsonPropertyInfo1.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.JsonMetadataServicesConverter1.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.JsonDictionaryConverter3.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.JsonConverter1.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.ObjectDefaultConverter1.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.JsonConverter1.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.JsonConverter1.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.JsonTypeInfo1.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(IResourceBuilder1 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