{"record":{"id":"dd30e359b6ea57e7","repo":"microsoft/aspire","slug":"the-microsoft-foundry-model-catalog-returned-no-models","errorCode":null,"errorMessage":"The Microsoft Foundry model catalog returned no models. Refusing to overwrite the generated model descriptors with an empty catalog.","messagePattern":"The Microsoft Foundry model catalog returned no models\\. Refusing to overwrite the generated model descriptors with an empty catalog\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Foundry/tools/GenModel.cs","lineNumber":27,"sourceCode":"using System.Linq;\nusing System.Text;\nusing System.Text.Json;\nusing System.Text.Json.Nodes;\nusing System.Text.Json.Serialization;\nusing System.Text.RegularExpressions;\nusing System.Xml.Linq;\nusing Markdig;\nusing Markdig.Syntax;\nusing Markdig.Syntax.Inlines;\n\nvar isFoundryLocal = args.Contains(\"--local\");\n\nusing var mc = new ModelClient(isFoundryLocal);\nvar allModelsResponse = await mc.GetAllModelsAsync().ConfigureAwait(false);\nvar models = allModelsResponse.Entities ?? [];\nif (models.Count == 0)\n{\n    throw new InvalidOperationException(\"The Microsoft Foundry model catalog returned no models. Refusing to overwrite the generated model descriptors with an empty catalog.\");\n}\n\nvar descriptorModels = isFoundryLocal\n    ? GetLocalDescriptorModels(models)\n    : GetDistinctHostedModels(models).ToList();\nif (descriptorModels.Count == 0)\n{\n    throw new InvalidOperationException(\"The Microsoft Foundry model catalog produced no model descriptors after filtering. Refusing to overwrite the generated model descriptors with an empty catalog.\");\n}\n\n// Generate C# extension methods for the models\nvar generatedCode = isFoundryLocal\n    ? GenerateLocalCode(\"Aspire.Hosting.Foundry\", descriptorModels)\n    : GenerateHostedCode(\"Aspire.Hosting.Foundry\", descriptorModels);\n\n// Write the generated code to a file\nvar filename = isFoundryLocal\n    ? Path.Combine(\"..\", \"FoundryModel.Local.Generated.cs\")","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Foundry/tools/GenModel.cs#L9-L45","documentation":"GenModel.cs is a source-generator tool that fetches the Microsoft Foundry model catalog and regenerates model descriptor extension methods. It throws this InvalidOperationException when the catalog API call succeeded but returned zero entities, because regenerating the checked-in generated files from an empty catalog would silently delete all model APIs. It is a deliberate safety guard against persisting an empty/incorrect catalog snapshot.","triggerScenarios":"Running the GenModel tool when ModelClient.GetAllModelsAsync() returns a response whose Entities collection is empty (models.Count == 0) — e.g. the Foundry catalog API returned a valid envelope with no model entries.","commonSituations":"Foundry service outage or API behavior change returning empty entity lists; querying with wrong flags (isFoundryLocal pointing at an empty local catalog); transient backend state where the catalog index is temporarily empty; network proxies stripping response payloads.","solutions":["Re-run the tool after confirming the Foundry catalog endpoint is healthy; the empty response is often transient.","Inspect the raw HTTP response (add logging in ModelClient.GetAllModelsAsync) to confirm whether the API truly returned zero entities or the deserialization dropped them.","Verify the isFoundryLocal flag and endpoint URL: a wrong endpoint can serve an empty catalog.","If the catalog genuinely has no models, do not regenerate — keep the existing generated descriptors and investigate the service side."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before regenerating, sanity-check the fetched catalog\nvar models = allModelsResponse.Entities ?? [];\nif (models.Count == 0)\n{\n    Console.WriteLine(\"Foundry catalog returned no models; skipping regeneration.\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await RunGenModelAsync();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"returned no models\"))\n{\n    // transient/empty catalog: log and retry later, keep existing generated files\n}","preventionTips":["Run codegen only when the Foundry endpoint is known healthy","Verify the isFoundryLocal flag matches the target endpoint","Keep existing generated files in version control so failures are visible","Check Foundry service status before scheduled regeneration runs"],"tags":["code-generation","empty-result-set","azure-foundry","tooling"],"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"}