From c16d767dff94bfe6c9f2c85ce1505cf05812c43e Mon Sep 17 00:00:00 2001 From: Gyumin Lee <64009299+Chi-square-test@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:47:53 +0900 Subject: [PATCH] fix: add defensive checks for missing model cost and capabilities fields (#855) OpenCode v1.3.13 may omit cost and capabilities from provider model config responses. The deriveModelMetadata function accessed these fields without optional chaining, causing a TypeError that crashes the chat interface. --- packages/ui/src/stores/useConfigStore.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/ui/src/stores/useConfigStore.ts b/packages/ui/src/stores/useConfigStore.ts index e965bec0..f6614888 100644 --- a/packages/ui/src/stores/useConfigStore.ts +++ b/packages/ui/src/stores/useConfigStore.ts @@ -234,7 +234,8 @@ const buildModelMetadataKey = (providerId: string, modelId: string) => { return `${normalizedProvider}/${modelId}`; }; -const mapModalities = (cap: { text: boolean; audio: boolean; image: boolean; video: boolean; pdf: boolean }): string[] => { +const mapModalities = (cap: { text: boolean; audio: boolean; image: boolean; video: boolean; pdf: boolean } | undefined): string[] => { + if (!cap) return []; const result: string[] = []; if (cap.text) result.push('text'); if (cap.audio) result.push('audio'); @@ -248,20 +249,20 @@ const deriveModelMetadata = (providerId: string, model: ProviderModel): ModelMet id: model.id, providerId, name: model.name, - tool_call: model.capabilities.toolcall, - reasoning: model.capabilities.reasoning, - temperature: model.capabilities.temperature, - attachment: model.capabilities.attachment, - modalities: { + tool_call: model.capabilities?.toolcall, + reasoning: model.capabilities?.reasoning, + temperature: model.capabilities?.temperature, + attachment: model.capabilities?.attachment, + modalities: model.capabilities ? { input: mapModalities(model.capabilities.input), output: mapModalities(model.capabilities.output), - }, - cost: { + } : undefined, + cost: model.cost ? { input: model.cost.input, output: model.cost.output, - cache_read: model.cost.cache.read, - cache_write: model.cost.cache.write, - }, + cache_read: model.cost.cache?.read, + cache_write: model.cost.cache?.write, + } : undefined, limit: model.limit, release_date: model.release_date, });