Skip to content

TypeScript AppHost deploy/publish starts DCP when launched through Yarn Classic because operation args are dropped #16616

@davidfowl

Description

@davidfowl

Summary

aspire deploy / aspire publish can hang for a TypeScript AppHost when the AppHost is launched through Yarn Classic. The CLI logs show it intends to pass publish/deploy operation arguments to the AppHost, but Yarn 1.22 drops those arguments unless a -- separator is used. As a result, the TypeScript AppHost runs as if no --operation publish --step deploy arguments were provided, so builder.build().run() enters normal run mode and starts DCP.

DCP should not be involved in deploy/publish.

Environment

  • Aspire CLI: 13.3.0+be8c19e483c7fca17f64510d1713ce5228a58843
  • Build ID: 13.300.26.22906
  • OS: macOS
  • Node: v22.20.0
  • npm: 10.9.3
  • Yarn: 1.22.22
  • AppHost: TypeScript apphost.ts

Repro

With a TypeScript AppHost that ends with:

await builder.build().run();

Run:

NO_COLOR=1 aspire deploy --apphost apphost.ts --debug --non-interactive

or:

NO_COLOR=1 aspire publish --apphost apphost.ts --debug --non-interactive

The command hangs after the pre-start deployment pipeline steps.

Observed behavior

The Aspire CLI debug log shows the TypeScript AppHost is launched like this:

Launching: yarn exec tsx --tsconfig tsconfig.apphost.json /path/to/apphost.ts --operation publish --step deploy
Executing: /path/to/yarn exec tsx --tsconfig tsconfig.apphost.json /path/to/apphost.ts --operation publish --step deploy

But with Yarn Classic, the AppHost does not receive the trailing args. A minimal argv probe shows:

yarn --silent exec tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts --operation publish --step deploy

prints:

["node","/path/to/argv-probe.ts"]

So .modules/aspire.ts uses:

args: options?.args ?? process.argv.slice(2)

and sends no --operation publish --step deploy args to Aspire.Hosting/createBuilder.

The AppHost then behaves like a normal run and starts DCP. During the hung deploy, the process tree included:

dcp start-apiserver ...
dcp run-controllers ...
aspire-managed dashboard ...

Expected behavior

aspire deploy and aspire publish should not start DCP. The TypeScript AppHost should receive the operation args and execute the publish/deploy pipeline path.

Additional evidence

Adding a -- separator before the AppHost args preserves them with Yarn Classic:

yarn --silent exec tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts -- --operation publish --step deploy

prints:

["node","/path/to/argv-probe.ts","--operation","publish","--step","deploy"]

This form also works:

yarn --silent exec -- tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts --operation publish --step deploy

Direct tsx also preserves the args:

node_modules/.bin/tsx --tsconfig tsconfig.apphost.json ./argv-probe.ts --operation publish --step deploy

Suspected fix

When launching TypeScript AppHosts through Yarn Classic, Aspire should insert an argument separator so AppHost args are forwarded, for example:

yarn exec tsx --tsconfig tsconfig.apphost.json apphost.ts -- --operation publish --step deploy

or:

yarn exec -- tsx --tsconfig tsconfig.apphost.json apphost.ts --operation publish --step deploy

The current launch form appears to let Yarn consume/drop the AppHost operation args.

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions