Skip to content

Harden diagnostics when integration-assembly resolver discovers zero contributors #16729

@IEvangelist

Description

@IEvangelist

Note

Updated 2026-05-04: The originally-reported 13.3.0 reproduction is no longer reproducible after clearing ~/.nuget and ~/.aspire on the reporter''s machine. The symptom appears to have been a stale local NuGet cache anomaly — the reporter had been switching between PR / staging / stable 13.3.0 builds, and a package on disk versioned 13.3.0 carried inconsistent contents relative to the rest of the 13.3.0 set. So this is not a release/13.3 ship blocker.

This issue is repurposed to track the diagnostic hardening so that any future failure with the same symptom (cache anomaly, build-pipeline skew, transitive package mismatch, partially populated probe directory, etc.) is loud and self-explanatory instead of producing only the cryptic surface error.

Symptom

aspire new with a TypeScript template fails before any project files are scaffolded:

  • Empty (TypeScript AppHost)❌ An unexpected error occurred: No language support found for: typescript/nodejs
  • Starter App (Express/React, TypeScript AppHost)❌ An unexpected error occurred: No code generator found for language: TypeScript

Both errors come out of the apphost RPC server (aspire-managed.exe server):

Why this is bad

When the resolver fails, the user sees a one-line cryptic error and nothing else. The actual failure mode (e.g., ReflectionTypeLoadException from assembly.GetTypes(), or a successful load that contributes zero discoverable types) is logged at LogDebug, which is below the file logger''s default Information threshold and never reaches the CLI''s on-disk log. So the user has no path to self-diagnose.

What we''re doing about it

PR #16733 hardens the diagnostic chain at every layer:

  1. CodeGeneratorResolver / LanguageSupportResolver log ReflectionTypeLoadException at Warning level and include the LoaderExceptions text.
  2. When an assembly named like Aspire.Hosting.CodeGeneration.* is loaded but contributes zero ICodeGenerator / ILanguageSupport types, a Warning is logged so the silent-failure case is visible.
  3. AssemblyLoader.LoadAssemblies performs an Aspire.TypeSystem version sanity check against the libs directory at startup and warns on mismatch.
  4. LanguageService / CodeGenerationService error messages now list the available languages, or point at the apphost-server log + binary mismatch when zero have been discovered.
  5. PrebuiltAppHostServer promotes apphost-server stdout/stderr capture from Trace to Debug / Information, so warnings emitted by the apphost server actually reach the default file log.

After this lands, a recurrence of the original symptom would surface a clear log entry naming the offending assembly and the version mismatch (or the swallowed ReflectionTypeLoadException), making the underlying cause obvious to both the user and to support.

Original report (preserved for context)

CLI version + invocation that produced the symptom
aspire --version
13.3.0+ee860bda2a0c813a9a07b26aa988ae7c279d5562

aspire new
# Select template: Empty (TypeScript AppHost)
# ...
# ❌ An unexpected error occurred: No language support found for: typescript/nodejs

aspire new
# Select template: Starter App (Express/React, TypeScript AppHost)
# ...
# ❌ An unexpected error occurred: No code generator found for language: TypeScript
aspire new aspire-ts-empty --name empty-ts --output ./empty-ts --localhost-tld true --non-interactive
aspire new aspire-ts-starter --name favs --output ./favs --localhost-tld true --non-interactive
Investigation summary

End-to-end trace against the reporter''s machine confirmed:

  1. The required Aspire.Hosting.CodeGeneration.TypeScript.dll (and full transitive closure) was on disk at ~/.aspire/packages/restore/<hash>/libs/.
  2. Reflection-only inspection showed both AtsTypeScriptCodeGenerator : ICodeGenerator (Language = "TypeScript") and TypeScriptLanguageSupport : ILanguageSupport (Language = "typescript/nodejs") with public parameterless constructors.
  3. The apphost server''s bundle-hosts/<hash>/appsettings.json listed the assembly correctly under AtsAssemblies.
  4. AssemblyLoader did load the assembly into the IntegrationLoadContext (confirmed by capturing the inner-process stdout via a wrapper exe with Logging__LogLevel__Default=Debug).
  5. AtsContext discovery on the loaded assembly succeeded (hundreds of [ATS] Discovered: ... entries).
  6. A standalone reproducer with the same IntegrationLoadContext shape against the same libs directory did find both types.

Yet inside the bundled aspire-managed.exe, both resolvers returned null. The most plausible explanations were a type-identity mismatch on Aspire.TypeSystem.ILanguageSupport / ICodeGenerator between the bundled and probed Aspire.TypeSystem copies, or a ReflectionTypeLoadException whose surviving ex.Types happened to omit those two types — both invisible to the user because the resolver swallowed the exception at LogDebug and the file logger filtered it out.

After clearing ~/.nuget and ~/.aspire, the failure stopped reproducing, consistent with a stale-cache anomaly. Diagnostic hardening (this issue) is the durable fix.

Suspected locations (now instrumented by #16733)

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions