{"record":{"id":"23446f4f83a7b7a5","repo":"microsoft/aspire","slug":"the-microsoft-foundry-model-catalog-returned-the-same","errorCode":null,"errorMessage":"The Microsoft Foundry model catalog returned the same continuation token twice. Refusing to overwrite the generated model descriptors with a partial catalog. Response: {GetResponseSnippet(pageResponse)}","messagePattern":"The Microsoft Foundry model catalog returned the same continuation token twice\\. Refusing to overwrite the generated model descriptors with a partial catalog\\. Response: (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Foundry/tools/GenModel.cs","lineNumber":783,"sourceCode":"            foreach (var model in pageModels)\n            {\n                allModels.Add(model);\n            }\n\n            Console.WriteLine($\"Fetched page with {pageModels.Count} models. Total so far: {allModels.Count}\");\n\n            // Check if there's a continuation token for the next page\n            previousToken = continuationToken;\n            continuationToken = apiResponse?.IndexEntitiesResponse?.ContinuationToken;\n\n            if (!string.IsNullOrEmpty(continuationToken))\n            {\n                Console.WriteLine($\"Found continuation token for next page: {continuationToken.Substring(0, Math.Min(50, continuationToken.Length))}...\");\n\n                // Check for infinite loop (same token repeated)\n                if (continuationToken == previousToken)\n                {\n                    throw new InvalidOperationException($\"The Microsoft Foundry model catalog returned the same continuation token twice. Refusing to overwrite the generated model descriptors with a partial catalog. Response: {GetResponseSnippet(pageResponse)}\");\n                }\n            }\n\n        } while (!string.IsNullOrEmpty(continuationToken));\n\n        Console.WriteLine($\"\\n=== Pagination Complete ===\");\n        Console.WriteLine($\"Total pages fetched: {pageCount}\");\n        Console.WriteLine($\"Total models collected: {allModels.Count}\");\n\n        RunFixups(allModels);\n\n        // Return the consolidated response using our model\n        return new ConsolidatedResponse\n        {\n            TotalCount = allModels.Count,\n            PagesCombined = \"All pages fetched\",\n            Entities = allModels\n        };","sourceCodeStart":765,"sourceCodeEnd":801,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Foundry/tools/GenModel.cs#L765-L801","documentation":"While paging the Foundry catalog, GetAllModelsAsync tracks the previous continuation token and throws if the service returns the identical token twice, which would loop forever and produce a partial catalog. The guard exists so generated descriptors are never overwritten from an incomplete page walk.","triggerScenarios":"The Foundry catalog's next-page continuation token does not advance — consecutive pages return the same token — inside the do/while pagination loop of GetAllModelsAsync.","commonSituations":"Foundry service bug or degraded state where the next-page link is stale; cached/proxied responses replaying the same page; API version mismatch causing the server to ignore paging parameters; index larger than the server can page correctly.","solutions":["Retry the tool run after some time — repeated identical tokens from a degraded service are often transient.","Inspect the response snippet to see the token values and confirm the server is not advancing pagination.","Check whether a proxy/cache is serving stale pages; bypass caching or add no-cache headers in ModelClient.","Verify the requested API version supports continuation tokens as the tool sends them; adjust paging parameters if the contract changed."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    await RunGenModelAsync();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"same continuation token twice\"))\n{\n    // service-side paging stall: back off and retry the whole run\n}","preventionTips":["Bypass caches/proxies for catalog requests to avoid stale pages","Retry the full pagination run with backoff on repeated tokens","Monitor Foundry API version changes affecting continuation tokens","Cap total pages walked as an additional loop guard"],"tags":["pagination","infinite-loop-guard","azure-foundry"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}