Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 1, 2025

Fix: WithVSCodeDebugSupport ServiceProvider Access Issue During Manifest Generation

Fixes a regression in Aspire 9.5.0 where using AddPythonApp with AddAzureContainerAppEnvironment causes manifest generation (azd infra gen) to fail with "IServiceProvider is not available" error.

Root Cause

When AzureResourcePreparer.GetAzureReferences() evaluates command line argument callbacks to discover Azure resource references, it was creating CommandLineArgsCallbackContext without setting the ExecutionContext property. This caused the context to default to Run mode instead of inheriting the actual execution context (Publish mode during manifest generation).

The WithVSCodeDebugSupport callback (introduced in 9.5.0 for Python apps) checks ctx.ExecutionContext.IsRunMode before accessing ctx.ExecutionContext.ServiceProvider. With the incorrect default context, this check failed, causing the callback to attempt accessing ServiceProvider during manifest generation where it's not available.

Changes Made

  1. Set ExecutionContext in AzureResourcePreparer - Set the ExecutionContext property when creating CommandLineArgsCallbackContext in AzureResourcePreparer.GetAzureReferences() to match the pattern already used for EnvironmentCallbackContext

  2. Only execute WithVSCodeDebugSupport in run mode - Modified WithVSCodeDebugSupport to return early when not in run mode, preventing both the WithArgs callback registration and the SupportsDebuggingAnnotation from being added during publish mode

  3. Added tests - Added tests to verify:

    • WithVSCodeDebugSupport correctly adds the annotation in run mode
    • WithVSCodeDebugSupport does not add the annotation in publish mode
    • CommandLineArgsCallbackContext has the correct ExecutionContext set during publish operations

Impact

  • Python apps (and other resources using WithVSCodeDebugSupport) now work correctly with Azure Container Apps during manifest generation
  • Command line argument callbacks receive the correct execution context, allowing them to make proper IsRunMode vs IsPublishMode decisions
  • Defense-in-depth: WithVSCodeDebugSupport callbacks and debugging annotations are only registered when appropriate for the execution mode
  • Minimal changes with no breaking changes or behavioral modifications for existing functionality

Testing

  • Added regression test CommandLineArgsCallbackContextHasCorrectExecutionContextDuringPublish that verifies callbacks receive the correct execution context during publish operations
  • Added test WithVSCodeDebugSupportAddsAnnotationInRunMode to verify the SupportsDebuggingAnnotation is correctly added in run mode
  • Added test WithVSCodeDebugSupportDoesNotAddAnnotationInPublishMode to verify the annotation is not added in publish mode

Fixes #11781

Original prompt

This section details on the original issue you should resolve

<issue_title>WithVSCodeDebugSupport in Python 9.5.0 causes IServiceProvider error with AddAzureContainerAppEnvironment during manifest generation (azd infra gen)</issue_title>
<issue_description>## Description

When using AddAzureContainerAppEnvironment together with AddPythonApp in Aspire 9.5.0, running azd infra gen (manifest generation) fails with an IServiceProvider is not available error. This is a regression in 9.5.0 - the same code works correctly in 9.4.2.

Environment

  • .NET Aspire version: 9.5.0
  • .NET SDK version: 9.0
  • OS: macOS (also reproduces on Windows/Linux)
  • Tool: Azure Developer CLI (azd)

Steps to Reproduce

  1. Create an AppHost project with Aspire 9.5.0

  2. Add the following packages:

    <PackageReference Include="Aspire.Hosting.AppHost" Version="9.5.0" />
    <PackageReference Include="Aspire.Hosting.Python" Version="9.5.0" />
    <PackageReference Include="Aspire.Hosting.Azure.AppContainers" Version="9.5.0" />
  3. Configure AppHost.cs with both Azure Container App Environment and Python app:

    var builder = DistributedApplication.CreateBuilder(args);
    
    var containerAppEnvironment = builder.AddAzureContainerAppEnvironment("containerAppEnvironment");
    
    var pythonapp = builder.AddPythonApp("instrumented-python-app", "../InstrumentedPythonProject", "app.py")
           .WithHttpEndpoint(env: "PORT")
           .WithExternalHttpEndpoints();
    
    builder.Build().Run();
  4. Run azd infra gen

Expected Behavior

Manifest generation should succeed and produce infrastructure files.

Actual Behavior

The command fails with the following error:

ERROR: generating apphost manifest: generating app host manifest: dotnet run --publisher manifest on project
'AspireWithPython.AppHost.csproj' failed: exit code: 134

Unhandled exception. System.AggregateException: One or more errors occurred.
(IServiceProvider is not available because execution context was not constructed with DistributedApplicationExecutionContextOptions.)
 ---> System.InvalidOperationException: IServiceProvider is not available because execution context was not
 constructed with DistributedApplicationExecutionContextOptions.
   at Aspire.Hosting.DistributedApplicationExecutionContext.get_ServiceProvider()
      in /_/src/Aspire.Hosting/DistributedApplicationExecutionContext.cs:line 67
   at Aspire.Hosting.ResourceBuilderExtensions.<>c__DisplayClass71_0`1.<WithVSCodeDebugSupport>b__0(CommandLineArgsCallbackContext ctx)
      in /_/src/Aspire.Hosting/ResourceBuilderExtensions.cs:line 2322
   at Aspire.Hosting.ResourceBuilderExtensions.<>c__DisplayClass14_0`1.<WithArgs>b__0(CommandLineArgsCallbackContext context)
      in /_/src/Aspire.Hosting/ResourceBuilderExtensions.cs:line 323
   at Aspire.Hosting.Azure.AzureResourcePreparer.GetAzureReferences(IResource resource, CancellationToken cancellationToken)
      in /_/src/Aspire.Hosting.Azure/AzureResourcePreparer.cs:line 387
   at Aspire.Hosting.Azure.AzureResourcePreparer.BuildRoleAssignmentAnnotations(DistributedApplicationModel appModel, List`1 azureResources, AzureProvisioningOptions options, CancellationToken cancellationToken)
      in /_/src/Aspire.Hosting.Azure/AzureResourcePreparer.cs:line 142
   at Aspire.Hosting.Azure.AzureResourcePreparer.BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken)
      in /_/src/Aspire.Hosting.Azure/AzureResourcePreparer.cs:line 39
   at Aspire.Hosting.DistributedApplication.ExecuteBeforeStartHooksAsync(CancellationToken cancellationToken)
      in /_/src/Aspire.Hosting/DistributedApplication.cs:line 490
   at Aspire.Hosting.DistributedApplication.RunAsync(CancellationToken cancellationToken)
      in /_/src/Aspire.Hosting/DistributedApplication.cs:line 440

Root Cause Analysis

  1. New Feature in 9.5.0: WithVSCodeDebugSupport was added to AddPythonApp in Aspire 9.5.0 to enable VS Code debugging support (see diff)

  2. The Conflict: When AddAzureContainerAppEnvironment is present, the AzureResourcePreparer.BeforeStartAsync lifecycle hook runs during manifest generation and calls GetAzureReferences(), which evaluates all args callbacks to discover Azure resource references

  3. The Bug: The WithVSCodeDebugSupport callback attempts to access ctx.ExecutionContext.ServiceProvider, but during manifest generation, the execution context wasn't constructed with DistributedApplicationExecutionContextOptions, causing the ServiceProvider property getter to throw an exception before the IsRunMode check can execute

  4. Why 9.4.2 Works: The Python package in 9.4.2 does not include WithVSCodeDebugSupport, so this callback never exists

Impact

This regression affects any Aspire 9.5.0 project that:

  • Uses ...
Fixes #11781

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…reparer

Set the ExecutionContext property when creating CommandLineArgsCallbackContext in AzureResourcePreparer.GetAzureReferences() to match how EnvironmentCallbackContext is created. This ensures callbacks receive the correct execution context (Publish vs Run mode), preventing WithVSCodeDebugSupport from incorrectly attempting to access ServiceProvider during manifest generation.

Co-authored-by: davidfowl <[email protected]>
Copilot AI changed the title [WIP] WithVSCodeDebugSupport in Python 9.5.0 causes IServiceProvider error with AddAzureContainerAppEnvironment during manifest generation (azd infra gen) Fix CommandLineArgsCallbackContext ExecutionContext in AzureResourcePreparer Oct 1, 2025
Copilot AI requested a review from davidfowl October 1, 2025 19:52
Copilot finished work on behalf of davidfowl October 1, 2025 19:53
@davidfowl
Copy link
Member

@copilot Also change WithVSCodeDebugSupport to only execute if builder.ApplicationBuilder.ExecutionContext.IsRunMode is true.

Add check at method level to only register WithArgs callback when builder.ApplicationBuilder.ExecutionContext.IsRunMode is true. This prevents the callback from being registered during publish mode, avoiding unnecessary callback evaluation during manifest generation.

Co-authored-by: davidfowl <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 1, 2025

@copilot Also change WithVSCodeDebugSupport to only execute if builder.ApplicationBuilder.ExecutionContext.IsRunMode is true.

Done in 1348d79. Added check at method level to only register the WithArgs callback when builder.ApplicationBuilder.ExecutionContext.IsRunMode is true, preventing the callback from being registered during publish mode.

Copilot AI changed the title Fix CommandLineArgsCallbackContext ExecutionContext in AzureResourcePreparer Fix CommandLineArgsCallbackContext ExecutionContext in AzureResourcePreparer and prevent WithVSCodeDebugSupport execution in publish mode Oct 1, 2025
Copilot finished work on behalf of davidfowl October 1, 2025 20:09
@github-actions
Copy link
Contributor

github-actions bot commented Oct 1, 2025

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 11783

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 11783"

@davidfowl
Copy link
Member

@copilot add a test for WithVSCodeDebugSupport not applying in publish mode (there should be no annotation)

@davidfowl davidfowl marked this pull request as ready for review October 1, 2025 20:22
Copilot AI review requested due to automatic review settings October 1, 2025 20:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request fixes a regression in Aspire 9.5.0 where using AddPythonApp with AddAzureContainerAppEnvironment causes manifest generation to fail with an "IServiceProvider is not available" error. The issue stems from incorrect execution context handling in command line argument callbacks during publish mode.

Key changes:

  • Sets the correct ExecutionContext in AzureResourcePreparer.GetAzureReferences() when creating CommandLineArgsCallbackContext
  • Prevents WithVSCodeDebugSupport from registering callbacks during publish mode by checking execution context at the method level
  • Adds a regression test to verify command line argument callbacks receive the correct execution context

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/Aspire.Hosting.Azure/AzureResourcePreparer.cs Sets ExecutionContext property when creating CommandLineArgsCallbackContext to match the actual execution mode
src/Aspire.Hosting/ResourceBuilderExtensions.cs Moves execution context check to method level to prevent callback registration during publish mode
tests/Aspire.Hosting.Azure.Tests/AzureResourcePreparerTests.cs Adds regression test verifying callbacks receive correct execution context during publish operations

Added tests to verify that WithVSCodeDebugSupport does not add the SupportsDebuggingAnnotation in publish mode, only in run mode. This ensures the debugging annotation is only added when appropriate.

Co-authored-by: davidfowl <[email protected]>
Copilot AI requested a review from mitchdenny as a code owner October 1, 2025 20:36
Copy link
Contributor Author

Copilot AI commented Oct 1, 2025

@copilot add a test for WithVSCodeDebugSupport not applying in publish mode (there should be no annotation)

Done in 72ae992. Added tests WithVSCodeDebugSupportAddsAnnotationInRunMode and WithVSCodeDebugSupportDoesNotAddAnnotationInPublishMode to verify the annotation is only added in run mode.

Copilot AI requested a review from davidfowl October 1, 2025 20:37
Copilot finished work on behalf of davidfowl October 1, 2025 20:37
Comment on lines 2330 to 2332
builder.WithAnnotation(new SupportsDebuggingAnnotation(projectPath, debugAdapterId, requiredExtensionId));

return builder;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
builder.WithAnnotation(new SupportsDebuggingAnnotation(projectPath, debugAdapterId, requiredExtensionId));
return builder;
return builder.WithAnnotation(new SupportsDebuggingAnnotation(projectPath, debugAdapterId, requiredExtensionId));

(nit) this can be reverted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in d421906. Reverted the formatting change.

Comment on lines 249 to 257
// This simulates WithVSCodeDebugSupport behavior - checking IsRunMode before accessing ServiceProvider
if (!context.ExecutionContext.IsRunMode)
{
return;
}

// This should not be reached during publish mode, but if the ExecutionContext is not set correctly,
// it will default to Run mode and then try to access ServiceProvider which will throw
_ = context.ExecutionContext.ServiceProvider;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. we don't need the IsRunMode check. That can be removed.
  2. You can set the IServiceProvider to a variable outside of the callback on line 243, and then Assert that it is not null at the end of the test on line 267.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in d421906. Removed the IsRunMode check and updated the test to capture the ExecutionContext and assert it's not null and in Publish mode.

@davidfowl
Copy link
Member

@copilot implement PR feedback.

- Reverted formatting change in ResourceBuilderExtensions.cs (return statement on one line)
- Improved CommandLineArgsCallbackContextHasCorrectExecutionContextDuringPublish test to:
  - Remove unnecessary IsRunMode check in callback
  - Capture ExecutionContext to verify it's set correctly
  - Assert ExecutionContext is not null and in Publish mode

Co-authored-by: davidfowl <[email protected]>
Copy link
Contributor Author

Copilot AI commented Oct 1, 2025

@copilot implement PR feedback.

Implemented in d421906.

Copilot finished work on behalf of davidfowl October 1, 2025 21:42
@davidfowl davidfowl merged commit 9136c2f into main Oct 1, 2025
618 of 621 checks passed
@davidfowl
Copy link
Member

/backport to release/9.5

@github-actions
Copy link
Contributor

github-actions bot commented Oct 1, 2025

@dotnet-policy-service dotnet-policy-service bot added this to the 13.0 milestone Oct 1, 2025
radical pushed a commit that referenced this pull request Oct 2, 2025
…reparer and prevent WithVSCodeDebugSupport execution in publish mode (#11783)

* Initial plan

* Fix CommandLineArgsCallbackContext ExecutionContext in AzureResourcePreparer

Set the ExecutionContext property when creating CommandLineArgsCallbackContext in AzureResourcePreparer.GetAzureReferences() to match how EnvironmentCallbackContext is created. This ensures callbacks receive the correct execution context (Publish vs Run mode), preventing WithVSCodeDebugSupport from incorrectly attempting to access ServiceProvider during manifest generation.

Co-authored-by: davidfowl <[email protected]>

* Only execute WithVSCodeDebugSupport in run mode

Add check at method level to only register WithArgs callback when builder.ApplicationBuilder.ExecutionContext.IsRunMode is true. This prevents the callback from being registered during publish mode, avoiding unnecessary callback evaluation during manifest generation.

Co-authored-by: davidfowl <[email protected]>

* Update src/Aspire.Hosting/ResourceBuilderExtensions.cs

* Add tests for WithVSCodeDebugSupport behavior in publish mode

Added tests to verify that WithVSCodeDebugSupport does not add the SupportsDebuggingAnnotation in publish mode, only in run mode. This ensures the debugging annotation is only added when appropriate.

Co-authored-by: davidfowl <[email protected]>

* Address PR feedback: revert formatting and improve test

- Reverted formatting change in ResourceBuilderExtensions.cs (return statement on one line)
- Improved CommandLineArgsCallbackContextHasCorrectExecutionContextDuringPublish test to:
  - Remove unnecessary IsRunMode check in callback
  - Capture ExecutionContext to verify it's set correctly
  - Assert ExecutionContext is not null and in Publish mode

Co-authored-by: davidfowl <[email protected]>

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: davidfowl <[email protected]>
Co-authored-by: David Fowler <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WithVSCodeDebugSupport in Python 9.5.0 causes IServiceProvider error with AddAzureContainerAppEnvironment during manifest generation (azd infra gen)

3 participants