From 02b66b23e97146fc9e3a68db09c6d36005db5cbe Mon Sep 17 00:00:00 2001 From: Adam Hosker Date: Sat, 20 Dec 2025 21:21:29 +0000 Subject: [PATCH] fix: handle providers with no available models to prevent crashes --- packages/opencode/src/acp/agent.ts | 1 + packages/opencode/src/provider/provider.ts | 20 ++++++++++++++++---- packages/opencode/src/server/server.ts | 18 ++++++++++++++++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/opencode/src/acp/agent.ts b/packages/opencode/src/acp/agent.ts index 2817adf5d..50080d701 100644 --- a/packages/opencode/src/acp/agent.ts +++ b/packages/opencode/src/acp/agent.ts @@ -662,6 +662,7 @@ export namespace ACP { }) const availableModels = entries.flatMap((provider) => { const models = Provider.sort(Object.values(provider.models)) + if (models.length === 0) return [] return models.map((model) => ({ modelId: `${provider.id}/${model.id}`, name: `${provider.name}/${model.name}`, diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index b8d4dadbd..394794a77 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -529,14 +529,26 @@ export namespace Provider { function mergeProvider(providerID: string, provider: Partial) { const existing = providers[providerID] if (existing) { - // @ts-expect-error - providers[providerID] = mergeDeep(existing, provider) + const merged = mergeDeep(existing, provider) as Info + // Validate after merge - if no models, remove the provider entirely + if (Object.keys(merged.models || {}).length === 0) { + log.warn("Provider has no models after merge, removing", { providerID }) + delete providers[providerID] + return + } + providers[providerID] = merged return } const match = database[providerID] if (!match) return - // @ts-expect-error - providers[providerID] = mergeDeep(match, provider) + + const merged = mergeDeep(match, provider) as Info + // Validate immediately after creation - if no models, don't add to providers + if (Object.keys(merged.models || {}).length === 0) { + log.warn("Provider has no models from database, skipping", { providerID }) + return + } + providers[providerID] = merged } // extend database from config diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index 34e5c0623..19aa1fed0 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -1481,7 +1481,14 @@ export namespace Server { const providers = await Provider.list().then((x) => mapValues(x, (item) => item)) return c.json({ providers: Object.values(providers), - default: mapValues(providers, (item) => Provider.sort(Object.values(item.models))[0].id), + default: mapValues(providers, (item) => { + const sorted = Provider.sort(Object.values(item.models)) + if (sorted.length === 0) { + log.error("Provider has no models available", { providerID: item.id }) + return null + } + return sorted[0].id + }), }) }, ) @@ -1528,7 +1535,14 @@ export namespace Server { ) return c.json({ all: Object.values(providers), - default: mapValues(providers, (item) => Provider.sort(Object.values(item.models))[0].id), + default: mapValues(providers, (item) => { + const sorted = Provider.sort(Object.values(item.models)) + if (sorted.length === 0) { + log.error("Provider has no models available", { providerID: item.id }) + return null + } + return sorted[0].id + }), connected: Object.keys(connected), }) },