From 6689e414bb033da3b94350535101cf07a9596496 Mon Sep 17 00:00:00 2001 From: "clawsweeper[bot]" <274271284+clawsweeper[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 21:53:25 -0700 Subject: [PATCH] fix(gateway): avoid caching empty model catalogs Co-authored-by: openclaw-clawsweeper[bot] <280122609+openclaw-clawsweeper[bot]@users.noreply.github.com> --- src/gateway/server-model-catalog.test.ts | 18 ++++++++++++++++++ src/gateway/server-model-catalog.ts | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/gateway/server-model-catalog.test.ts b/src/gateway/server-model-catalog.test.ts index 00867a7773f..d8f85fa8f85 100644 --- a/src/gateway/server-model-catalog.test.ts +++ b/src/gateway/server-model-catalog.test.ts @@ -47,6 +47,24 @@ describe("loadGatewayModelCatalog", () => { expect(loadModelCatalog).toHaveBeenCalledTimes(1); }); + it("does not cache an empty catalog so the next request retries", async () => { + const emptyCatalog: GatewayModelChoice[] = []; + const freshCatalog = [model("gpt-5.5")]; + const loadModelCatalog = vi + .fn() + .mockResolvedValueOnce(emptyCatalog) + .mockResolvedValueOnce(freshCatalog); + + await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe( + emptyCatalog, + ); + await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe( + freshCatalog, + ); + + expect(loadModelCatalog).toHaveBeenCalledTimes(2); + }); + it("returns the last catalog while a stale reload refresh is still pending", async () => { const staleCatalog = [model("gpt-5.4")]; const freshCatalog = [model("gpt-5.5")]; diff --git a/src/gateway/server-model-catalog.ts b/src/gateway/server-model-catalog.ts index fee2b78ae60..586a0bd5c34 100644 --- a/src/gateway/server-model-catalog.ts +++ b/src/gateway/server-model-catalog.ts @@ -45,7 +45,7 @@ function startGatewayModelCatalogRefresh( const refresh = resolveLoadModelCatalog(params) .then((loadModelCatalog) => loadModelCatalog({ config })) .then((catalog) => { - if (refreshGeneration === staleGeneration) { + if (catalog.length > 0 && refreshGeneration === staleGeneration) { lastSuccessfulCatalog = catalog; appliedGeneration = staleGeneration; }