{"record":{"id":"548584dc4365f51a","repo":"microsoft/aspire","slug":"package-packagename-version-packageversion-was-mapped-from","errorCode":null,"errorMessage":"Package '{packageName}' version '{packageVersion}' was mapped from restored asset paths, but none of its assemblies reached the scanned API surface.","messagePattern":"Package '(.+?)' version '(.+?)' was mapped from restored asset paths, but none of its assemblies reached the scanned API surface\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs","lineNumber":401,"sourceCode":"    {\n        if (_assemblyLoader.TryGetPackageAssemblyNamesFromProbePaths(\n            packageName,\n            packageVersion,\n            out var manifestAssemblyNames,\n            out var manifestPackageName))\n        {\n            var exportingAssemblyNames = new List<string>(manifestAssemblyNames.Count);\n            foreach (var assemblyName in manifestAssemblyNames)\n            {\n                if (AtsContextFilter.TryResolveCanonicalAssemblyName(fullContext, assemblyName, out var canonicalAssemblyName))\n                {\n                    exportingAssemblyNames.Add(canonicalAssemblyName);\n                }\n            }\n\n            if (exportingAssemblyNames.Count == 0)\n            {\n                throw new InvalidOperationException(\n                    $\"Package '{packageName}' version '{packageVersion}' was mapped from restored asset paths, \" +\n                    \"but none of its assemblies reached the scanned API surface.\");\n            }\n\n            canonicalPackageName = manifestPackageName;\n            return exportingAssemblyNames;\n        }\n\n        // A NuGet package id is case-insensitive\n        // (https://learn.microsoft.com/nuget/consume-packages/finding-and-choosing-packages#package-identifiers)\n        // but the exported document records this string verbatim as the identity consumers key\n        // on, so `aspire.hosting.redis` would publish a document naming a package nobody looks\n        // up. For local project references and older probe manifests we do not have package-to-\n        // assembly metadata, so the loaded assembly settles the spelling as before.\n        if (!AtsContextFilter.TryResolveCanonicalAssemblyName(fullContext, packageName, out var canonicalAssemblyNameFromContext))\n        {\n            throw new InvalidOperationException(\n                $\"No managed assemblies for package '{packageName}' version '{packageVersion}' could be mapped from the restored asset paths, \" +","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.RemoteHost/CodeGeneration/CodeGenerationService.cs#L383-L419","documentation":"ResolvePackageExportingAssemblyNames maps a NuGet package id+version to the assembly names that contributed to the scanned API surface, using restored asset paths. If the mapping produced entries but none of the package's assemblies actually appear in the scanned API surface, it throws this InvalidOperationException. It guards against publishing source-generation documents keyed to a package whose code never made it into the scan.","triggerScenarios":"Calling code generation for a package whose asset-path manifest maps to assemblies that were excluded from the ATS scan (API-export filter, scoped-context filtering), so exportingAssemblyNames ends up empty after cross-checking the scanned surface.","commonSituations":"Requesting generation for a package that is referenced on disk but not part of the scanned app model; package restored but its assemblies filtered out by the export filter; stale manifest pointing at an old package layout.","solutions":["Reference the package in the AppHost so its assemblies participate in the scanned API surface.","Rerun generation without a scoped assemblyName, or scope to an assembly that is actually in the scan.","Clean and restore so the restored asset paths match the current package versions.","Verify the package actually contains managed assemblies for the target framework (not a metadata-only or tools-only package)."],"exampleFix":"// before: AppHost does not reference the package being generated for\n// after\n<PackageReference Include=\"Aspire.Hosting.Redis\" Version=\"9.2.0\" /> // package now reaches the scanned API surface","handlingStrategy":"validation","validationCode":"// ensure the package is referenced by the AppHost and present in the scanned surface\nvar scanned = await client.GetScannedAssemblyNames();\nif (!scanned.Any(a => a.StartsWith(\"Aspire.Hosting\", StringComparison.OrdinalIgnoreCase)))\n    throw new InvalidOperationException(\"Package assemblies absent from scanned API surface; reference the package in the AppHost.\");","typeGuard":"static bool PackageInScan(string packageName, IEnumerable<string> scannedAssemblies) =>\n    scannedAssemblies.Any(a => a.Equals(packageName, StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try { var asm = ResolvePackageExportingAssemblyNames(pkg, version, context); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"none of its assemblies reached the scanned API surface\"))\n{ log.LogError(ex, \"Package not part of scanned surface\"); throw; }","preventionTips":["Reference the package from the AppHost project so it participates in the scan.","Clean/restore after version changes so asset-path manifests are current.","Scope generation to assemblies that actually appear in the exported document."],"tags":["code-generation","nuget","package-mapping","ats"],"backgroundTag":"empty-result-set","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}