Skip to content

Fix TypeScript AppHost async callback deadlock#17575

Merged
IEvangelist merged 1 commit into
mainfrom
ievangelist/dapine-test-cli-repro
May 29, 2026
Merged

Fix TypeScript AppHost async callback deadlock#17575
IEvangelist merged 1 commit into
mainfrom
ievangelist/dapine-test-cli-repro

Conversation

@IEvangelist
Copy link
Copy Markdown
Member

Description

Fixes #17487.
Follow-up to #17508.

TypeScript AppHosts could still deadlock during await builder.build().run() when an async TypeScript callback was stored in lazy IOptions.Configure and invoked during BeforeStartEvent. PR #17508 fixed the dispatcher behavior for exports that already opt into RunSyncOnBackgroundThread, but the actual Aspire.Hosting/run capability was not opted in, so the real AppHost startup path could still run on StreamJsonRpc's non-concurrent synchronization context.

This changes DistributedApplication.RunAsync to export Aspire.Hosting/run with RunSyncOnBackgroundThread = true, keeping the synchronous startup portion of RunAsync off the JSON-RPC synchronization context. Existing TypeScript AppHosts can keep using:

await builder.build().run();

The PR also adds a CLI E2E regression that recreates the exact failure shape:

  1. Creates a TypeScript empty AppHost.
  2. Adds a local ATS extension whose exported method is marked RunSyncOnBackgroundThread = true.
  3. Stores the TypeScript async configure callback inside lazy IOptions.Configure.
  4. Resolves those options from BeforeStartEvent.
  5. Verifies aspire start succeeds instead of timing out while waiting for the AppHost server.

Validation:

  • .\restore.cmd
  • dotnet build tests\Aspire.Cli.EndToEnd.Tests\Aspire.Cli.EndToEnd.Tests.csproj /p:SkipNativeBuild=true
  • Built a local Windows hive from this branch with .\localhive.ps1 -r win-x64 -Archive.
  • Manually ran the exact TypeScript lazy-options repro against that hive: aspire restore, npm run build, aspire start --format Json, and aspire stop. aspire start returned successfully in ~15s instead of timing out after 60s.

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Run the exported DistributedApplication.RunAsync capability on a background thread so startup callbacks invoked before the first await do not block StreamJsonRpc's non-concurrent synchronization context.

Add an end-to-end TypeScript AppHost regression that recreates the lazy IOptions.Configure async callback pattern from #17487.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 28, 2026 03:02
@github-actions
Copy link
Copy Markdown
Contributor

🚀 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/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17575

Or

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

Copy link
Copy Markdown
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 PR fixes a TypeScript AppHost startup deadlock by ensuring the exported Aspire.Hosting/run capability runs its synchronous startup path off the JSON-RPC synchronization context.

Changes:

  • Marks DistributedApplication.RunAsync with RunSyncOnBackgroundThread = true.
  • Adds a TypeScript CLI E2E regression test that reproduces lazy IOptions.Configure invoking an async ATS callback during BeforeStartEvent.

Reviewed changes

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

File Description
src/Aspire.Hosting/DistributedApplication.cs Opts the run ATS export into background-thread invocation.
tests/Aspire.Cli.EndToEnd.Tests/TypeScriptEmptyAppHostTemplateTests.cs Adds regression coverage for the TypeScript lazy-options async callback deadlock scenario.

@IEvangelist IEvangelist marked this pull request as draft May 28, 2026 11:45
@github-actions
Copy link
Copy Markdown
Contributor

CLI E2E Tests failed — 106 passed, 2 failed, 2 unknown (commit 0bceda1)

❌ Failed Tests

Status Test Recording Job Artifacts
CreateAndRunEmptyAppHostProject Recording #78284581886 Logs
LatestCliCanStartStableChannelAppHost Recording #78284582589 Logs
View all recordings
Status Test Recording Job Artifacts
AddPackageInteractiveWhileAppHostRunningDetached Recording #78284582335 Logs
AddPackageWhileAppHostRunningDetached Recording #78284582335 Logs
AgentCommands_AllHelpOutputs_AreCorrect Recording #78284582841 Logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording #78284582841 Logs
AgentInitCommand_MigratesDeprecatedConfig Recording #78284582841 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording #78284583280 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording #78284583280 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording #78284583280 Logs
AllPublishMethodsBuildDockerImages Recording #78284582656 Logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording #78284583455 Logs
AspireAddPackageVersionToDirectoryPackagesProps Recording #78284582561 Logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording #78284582787 Logs
AspireInitWithExistingAppHostDirRecreatesMissingNuGetConfigAndPreservesFiles Recording #78284582941 Logs
AspireInitWithSolutionFileGeneratesAppHostThatBuildsAgainstChannelHive Recording #78284582941 Logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording #78284583207 Logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording #78284582561 Logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording #78284582561 Logs
Banner_DisplayedOnFirstRun Recording #78284583214 Logs
Banner_DisplayedWithExplicitFlag Recording #78284583214 Logs
Banner_NotDisplayedWithNoLogoFlag Recording #78284583214 Logs
CertificatesClean_RemovesCertificates Recording #78284583298 Logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording #78284583298 Logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording #78284583298 Logs
ConfigSetGet_CreatesNestedJsonFormat Recording #78284582438 Logs
CreateAndRunAspireStarterProject Recording #78284582589 Logs
CreateAndRunAspireStarterProjectWithBundle Recording #78284583495 Logs
CreateAndRunEmptyAppHostProject Recording #78284581886 Logs
CreateAndRunJavaEmptyAppHostProject Recording #78284583068 Logs
CreateAndRunJsReactProject Recording #78284582937 Logs
CreateAndRunPythonReactProject Recording #78284582497 Logs
CreateAndRunTypeScriptEmptyAppHostProject Recording #78284582111 Logs
CreateAndRunTypeScriptStarterProject Recording #78284582664 Logs
CreateJavaAppHostWithViteApp Recording #78284583116 Logs
CreateTypeScriptAppHostWithViteApp_AllowsGuestAppPackageManagerToDiffer Recording #78284582050 Logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording #78284582050 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording #78284582063 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording #78284582063 Logs
DashboardRunWithOtelTracesReturnsNoTraces Recording #78284582063 Logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording #78284582063 Logs
DeployK8sBasicApiService Recording #78284582400 Logs
DeployK8sWithExternalHelmChart Recording #78284583487 Logs
DeployK8sWithGarnet Recording #78284582341 Logs
DeployK8sWithMongoDB Recording #78284582110 Logs
DeployK8sWithMySql Recording #78284582520 Logs
DeployK8sWithPostgres Recording #78284583291 Logs
DeployK8sWithRabbitMQ Recording #78284583753 Logs
DeployK8sWithRedis Recording #78284582579 Logs
DeployK8sWithSqlServer Recording #78284582558 Logs
DeployK8sWithValkey Recording #78284582986 Logs
DeployTypeScriptAppToKubernetes Recording #78284583219 Logs
DescribeCommandResolvesReplicaNames Recording #78284583348 Logs
DescribeCommandShowsRunningResources Recording #78284583348 Logs
DetachFormatJsonProducesValidJson Recording #78284583305 Logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording #78284583305 Logs
DoPublishAndDeployListStepsWork Recording #78284582708 Logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording #78284582397 Logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording #78284582841 Logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording #78284583202 Logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording #78284583202 Logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording #78284583202 Logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78284583490 Logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording #78284582050 Logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording #78284582438 Logs
GlobalMigration_HandlesMalformedLegacyJson Recording #78284582438 Logs
GlobalMigration_PreservesAllValueTypes Recording #78284582438 Logs
GlobalMigration_SkipsWhenNewConfigExists Recording #78284582438 Logs
GlobalSettings_MigratedFromLegacyFormat Recording #78284582438 Logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78284583490 Logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording #78284582050 Logs
InteractiveCSharpInitCreatesExpectedFiles Recording #78284583164 Logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording #78284583255 Logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording #78284582656 Logs
LatestCliCanStartStableChannelAppHost Recording #78284582589 Logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording #78284582589 Logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording #78284583207 Logs
LogsCommandShowsResourceLogs Recording #78284583315 Logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording #78284582946 Logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording #78284582946 Logs
PsCommandListsRunningAppHost Recording #78284583702 Logs
PsFormatJsonOutputsOnlyJsonToStdout Recording #78284583702 Logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording #78284583344 Logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording #78284583344 Logs
PublishWithDockerComposeServiceCallbackSucceeds Recording #78284583344 Logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording #78284583344 Logs
ResourceCommand_FailedExecution_DisplaysAppHostLogPathAndLogContainsEntries Recording #78284582367 Logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording #78284582367 Logs
RestoreGeneratesSdkFiles Recording #78284582209 Logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording #78284581996 Logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording #78284581996 Logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording #78284583300 Logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording #78284583573 Logs
RunReportsSyntaxErrorsForDotNetAppHost Recording #78284583400 Logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording #78284583400 Logs
SecretCrudOnDotNetAppHost Recording #78284583043 Logs
SecretCrudOnTypeScriptAppHost Recording #78284582349 Logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording #78284582374 Logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording #78284582462 Logs
StartReportsSyntaxErrorsForDotNetAppHost Recording #78284583400 Logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording #78284583400 Logs
StopAllAppHostsFromAppHostDirectory Recording #78284582084 Logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording #78284583120 Logs
StopNonInteractiveSingleAppHost Recording #78284582084 Logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording #78284582555 Logs
StopWithNoRunningAppHostExitsSuccessfully Recording #78284582335 Logs
TypeScriptAppHostRunDoesNotDeadlockWhenLazyOptionsInvokeAsyncCallback Recording #78284582111 Logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording #78284581996 Logs
UpdateProjectChannelToStable_CSharpEmptyAppHost_PreservesAspireConfigChannel Recording #78284582944 Logs
UpdateProjectChannelToStable_CSharpSingleFileInit_PreservesAspireConfigChannel Recording #78284582944 Logs
UpdateProjectChannelToStable_TypeScriptSingleFileInit_PreservesAspireConfigChannel Recording #78284582944 Logs
UpdateProjectChannelToStable_TypeScript_PreviewsStablePackagesAndPreservesChannel Recording #78284582944 Logs

📹 Recordings uploaded automatically from CI run #26552008600

@IEvangelist
Copy link
Copy Markdown
Member Author

PR Testing Report

PR Information

CLI Version Verification

  • Expected Commit: 0bceda1
  • Installed Version: 13.5.0-pr.17575.g0bceda1c
  • Status: Verified - installed PR CLI version contains 0bceda1c

Changes Analyzed

Files Changed

  • src/Aspire.Hosting/DistributedApplication.cs - changed Aspire.Hosting/run export to RunSyncOnBackgroundThread = true
  • tests/Aspire.Cli.EndToEnd.Tests/TypeScriptEmptyAppHostTemplateTests.cs - added TypeScript async callback deadlock regression coverage

Change Categories

  • CLI changes detected
  • Hosting changes detected
  • Dashboard changes detected
  • Template changes detected
  • Client/Component changes detected
  • Test changes detected

Execution Environment Notes

  • The PowerShell container runner script failed under PowerShell Core because $IsWindows is a built-in read-only variable; retrying through Windows PowerShell avoided that issue.
  • The runner then remained stuck while rebuilding the existing aspire-pr-runner image at base-image metadata resolution, so I used the already-present aspire-pr-runner:latest image directly with the same /workspace and /workspace/.aspire mounts.
  • The container image did not include Node.js/npm or .NET SDK. I installed Node.js/npm in each scenario container and installed .NET SDK 10.0.300 into the isolated workspace at /workspace/.dotnet.

Test Scenarios Executed

Scenario 1: Simple TypeScript AppHost start/stop

Objective: Ensure the Aspire.Hosting/run export change does not break normal TypeScript empty AppHost startup.
Coverage Type: Happy path
Status: Passed

Steps:

  1. Created aspire-ts-empty project SimpleTsSmoke from the PR hive.
  2. Ran aspire restore --apphost apphost.mts.
  3. Ran npm run build.
  4. Ran aspire start --apphost apphost.mts --format Json.
  5. Ran aspire stop --apphost apphost.mts.

Evidence:

  • Log: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\scenario-1-simple-ts\scenario-output.txt
  • Start output: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\scenario-1-simple-ts\start-output.json

Observations:

  • AppHost started successfully and returned dashboard metadata.
  • AppHost stopped successfully.

Scenario 2: TypeScript lazy-options async callback deadlock regression

Objective: Recreate the PR's deadlock shape: a TypeScript async callback stored in lazy IOptions.Configure, resolved during BeforeStartEvent, with await builder.build().run().
Coverage Type: Happy path / Regression
Status: Passed

Steps:

  1. Created aspire-ts-empty project TsDeadlockRepro from the PR hive.
  2. Added local DeadlockExtension C# ATS extension using [AspireExport(RunSyncOnBackgroundThread = true)].
  3. Configured apphost.mts to set someProperty from an async TypeScript callback.
  4. Added the local extension package to aspire.config.json.
  5. Ran aspire restore --apphost apphost.mts.
  6. Ran npm run build.
  7. Ran timeout 240s aspire start --apphost apphost.mts --format Json.
  8. Ran aspire stop --apphost apphost.mts.

Evidence:

  • Log: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\scenario-2-deadlock-regression\scenario-output.txt
  • Start output: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\scenario-2-deadlock-regression\start-output.json

Observations:

  • aspire start completed successfully instead of timing out.
  • The lazy options callback set the expected value and the AppHost stopped cleanly.

Scenario 3: Callback validation failure

Objective: Verify the same async callback/startup path fails safely when the callback produces invalid configuration.
Coverage Type: Unhappy path
Status: Passed

Steps:

  1. Created aspire-ts-empty project TsDeadlockValidationFailure from the PR hive.
  2. Added the same local DeadlockExtension validation as Scenario 2.
  3. Configured apphost.mts to set someProperty to wrong-value.
  4. Ran aspire restore --apphost apphost.mts.
  5. Ran npm run build.
  6. Ran timeout 240s aspire start --apphost apphost.mts --format Json and expected a non-zero exit.
  7. Ran best-effort aspire stop --apphost apphost.mts.

Evidence:

  • Log: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\scenario-3-validation-failure\scenario-output.txt
  • Start output: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\scenario-3-validation-failure\start-output.txt

Expected Unhappy-Path Outcome: Clear startup failure/non-zero exit without hanging.

Observations:

  • aspire start exited with code 2, not a timeout.
  • Startup output included: Capability Error: Could not invoke 'run': Expected TypeScript callback to set someProperty, but got 'wrong-value'.

Summary

Scenario Status Notes
Version verification Passed Installed CLI version matched PR head 0bceda1c
Simple TypeScript start/stop Passed Normal TypeScript AppHost startup still works
Deadlock regression Passed Async lazy-options callback path completed without timeout
Callback validation failure Passed Invalid callback value failed clearly with non-zero exit

Overall Result

PR VERIFIED

No issues found in the tested TypeScript AppHost async callback startup scenarios.

Artifacts

  • Install log: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\install-output.txt
  • Version log: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\version.txt
  • Prerequisite setup log: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\prerequisites\prerequisites-output.txt
  • Scenario logs: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\scenario-*\scenario-output.txt
  • Captured Aspire logs: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-983352d187fe466b962bd596f5164128\captured-aspire-logs\

@IEvangelist
Copy link
Copy Markdown
Member Author

PR Testing Report

PR Information

CLI Version Verification

  • Expected Commit: 0bceda1
  • Installed Version: 13.5.0-pr.17575.g0bceda1c
  • Status: ✅ Verified

Changes Analyzed

Files Changed

  • src/Aspire.Hosting/DistributedApplication.cs - Modified
  • tests/Aspire.Cli.EndToEnd.Tests/TypeScriptEmptyAppHostTemplateTests.cs - Modified

Change Categories

  • CLI changes detected
  • Hosting changes detected
  • Dashboard changes detected
  • Template changes detected
  • Client/Component changes detected
  • Test changes detected

Test Scenarios Executed

PR CLI install/version verification

Objective: Install dogfood CLI and verify it matches PR head commit.
Coverage Type: Setup
Status: ✅ Passed

Steps:

  1. Installed the dogfood CLI from the PR comment
  2. Ran /workspace/.aspire/dogfood/pr-17575/bin/aspire --version
  3. Compared output with the PR head commit

Evidence:

  • Log: /workspace/artifacts/install.log
  • Version: /workspace/artifacts/version.txt

Observations:
Installed CLI version contains expected commit 0bceda1.


TypeScript empty AppHost smoke test

Objective: Verify a fresh TypeScript empty AppHost from the PR hive can be created, restored, built, started, and stopped.
Coverage Type: Happy path
Status: ✅ Passed

Steps:

  1. Created aspire-empty with --language typescript
  2. Restored packages non-interactively
  3. Ran npm run build
  4. Ran aspire start with an explicit AppHost path
  5. Ran aspire stop with an explicit AppHost path

Evidence:

  • Log: /workspace/artifacts/typescript-smoke.log

Observations:
Fresh TypeScript empty AppHost started and stopped successfully.


Async callback deadlock regression

Objective: Verify lazy options configured through an async TypeScript callback do not deadlock during AppHost startup.
Coverage Type: Happy path / Regression
Status: ✅ Passed

Steps:

  1. Created a fresh TypeScript empty AppHost
  2. Added a local C# extension package with an exported options callback
  3. Configured the option from an async TypeScript callback
  4. Restored packages and built the TypeScript AppHost
  5. Started and stopped the AppHost with explicit AppHost paths

Evidence:

  • Log: /workspace/artifacts/async-callback-deadlock-regression.log

Observations:
Async TypeScript callback completed and aspire start returned successfully.


Async callback error propagation

Objective: Verify an async TypeScript callback failure exits safely with a clear error rather than hanging.
Coverage Type: Unhappy path
Status: ✅ Passed

Steps:

  1. Created a fresh TypeScript empty AppHost
  2. Added the same local exported C# extension package
  3. Configured the TypeScript callback to throw asynchronously
  4. Restored and built the AppHost
  5. Ran aspire start and checked for non-zero exit plus the intentional error message

Evidence:

  • Log: /workspace/artifacts/async-callback-error-propagation.log

Observations:
aspire start exited non-zero and surfaced the intentional callback error.
Expected Unhappy-Path Outcome: A non-zero exit with intentional callback failure, no deadlock or timeout.


Summary

Scenario Status Notes
PR CLI install/version verification ✅ Passed Installed CLI version contains expected commit 0bceda1.
TypeScript empty AppHost smoke test ✅ Passed Fresh TypeScript empty AppHost started and stopped successfully.
Async callback deadlock regression ✅ Passed Async TypeScript callback completed and aspire start returned successfully.
Async callback error propagation ✅ Passed aspire start exited non-zero and surfaced the intentional callback error.

Overall Result

✅ PR VERIFIED

Recommendations

  • No issues found in the tested scenarios.

@IEvangelist IEvangelist marked this pull request as ready for review May 29, 2026 14:26
@IEvangelist IEvangelist merged commit 4cfc99d into main May 29, 2026
617 of 621 checks passed
@IEvangelist IEvangelist deleted the ievangelist/dapine-test-cli-repro branch May 29, 2026 19:24
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.5 milestone May 29, 2026
@aspire-repo-bot
Copy link
Copy Markdown
Contributor

✅ No documentation update needed.

docs_required → already documented by name

Triggered signal (1): pr_body_has_cli_flag_mention.

The signal fired because the PR body mentions aspire start --format Json in the manual validation section. This flag is already fully documented in the existing docs:

  • File: src/frontend/src/content/docs/reference/cli/commands/aspire-start.mdx
  • Quoted text: **\--format (Json|Table)`** — Output format for detached apphost results. Use `Json` for machine-readable output suitable for scripting and automation.(with an accompanying code example showingaspire start --format Json`)

The PR itself is a one-line bug fix (RunSyncOnBackgroundThread = true on RunAsync) plus a regression test. No new CLI flags, options, public APIs, or user-facing surface were introduced. The existing docs already describe the correct behavior for await builder.build().run() in TypeScript AppHosts.

@sebastienros
Copy link
Copy Markdown
Contributor

/backport to release/13.4

@github-actions
Copy link
Copy Markdown
Contributor

Started backporting to release/13.4 (link to workflow run)

adamint added a commit to adamint/aspire that referenced this pull request May 29, 2026
Pulls in microsoft#17701 (Fix TypeScript deadlock repro E2E test) so PR
GitHub Actions can complete. Main has been broken for PR events
since microsoft#17575 added a test calling RunCommandFailFastAsync which
microsoft#17588 renamed to RunCommandAsync. microsoft#17701 updates the call sites.

No infra changes from this branch are affected by this merge.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants