microsoft / microsoft/aspire

TypeScript AppHost does not diagnose invalid resource passed to withEnvironment

Open
#19,902 0 comments 0 reactions 0 assignees View on GitHub
area-polyglot bug
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

![TypeScript AppHost accepts the resource without an editor diagnostic](https://github.com/user-attachments/assets/277e3ff7-506f-424e-a2d0-8e164235fe9f)

### C# AppHost: inline compiler diagnostic

![C# AppHost reports an argument conversion error in the editor](https://github.com/user-attachments/assets/5174e553-00d4-4cac-b253-2ae399f1455e)

### 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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.