TypeScript AppHost does not diagnose invalid resource passed to withEnvironment
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
### Describe the bug
In a TypeScript `.mts` AppHost, the generated `withEnvironment` type allows a full resource builder to be passed as the environment-variable value even when that value will be rejected while building the AppHost.
The equivalent C# AppHost reports an editor/compiler error on the call, so the TypeScript failure is unexpectedly deferred until build/run time.
### TypeScript AppHost: no editor diagnostic

### C# AppHost: inline compiler diagnostic

### Expected behavior
The generated TypeScript API should reject resource-builder values that the `withEnvironment` runtime dispatcher cannot consume, producing an editor diagnostic at the call site just as the C# API does.
### Steps to reproduce
Using a TypeScript AppHost with the Azure Key Vault integration:
```typescript
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const secretValue = await builder.addParameter("secret-value", { secret: true });
const vault = await builder.addAzureKeyVault("vault");
const secret = await vault.addSecret("secret", secretValue);
const api = await builder.addContainer("api", "my-api");
// No TypeScript editor diagnostic, but building/running the AppHost fails.
await api.withEnvironment("SECRET", secret);
await builder.build().run();
```
### Investigation notes
On current `main` (`8780cb1`), the polyglot dispatcher declares `withEnvironment` as accepting `IExpressionValue`:
https://github.com/microsoft/aspire/blob/8780cb1/src/Aspire.Hosting/ResourceBuilderExtensions.cs#L239-L270
`AzureKeyVaultSecretResource` implements `IExpressionValue`, so TypeScript code generation can include its resource-builder wrapper in the value union:
https://github.com/microsoft/aspire/blob/8780cb1/src/Aspire.Hosting.Azure.KeyVault/api/Aspire.Hosting.Azure.KeyVault.cs#L79
The likely mismatch is that TypeScript passes the resource-builder handle, while the dispatcher branch expects the value itself as `IExpressionValue`. C# catches that distinction because `IResourceBuilder` is not itself an `IExpressionValue`.
_Created from a [Microsoft Teams conversation](https://teams.microsoft.com/l/message/19%3AuuDJgMCR7JeFSM-0RK2xRW5mAq2WFNfUK0TLmYDvAU01%40thread.tacv2/1788459629790?tenantId=72f988bf-86f1-41af-91ab-2d7cd011db47&groupId=f2e0b0b6-f130-46fa-8ec6-2ef4a7168ed2&parentMessageId=1788459629790)._
Contributor guide
Research direction
Start with src/Aspire/Hosting/ResourceBuilderExtensions.cs lines 239-270 and the AzureKeyVaultSecretResource declaration in src/Aspire.Hosting.Azure.KeyVault/api/Aspire.Hosting.Azure.KeyVault.cs. Reproduce the TypeScript AppHost example with the Azure Key Vault integration and inspect how the generated withEnvironment value union represents the resource builder. Done means the invalid value receives an editor diagnostic before build or run, matching the C# behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, csharp, typescript
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100