{"record":{"id":"b6cae173c18c1844","repo":"lbjlaq/Antigravity-Manager","slug":"apikeyfun-errors-queryfailed","errorCode":null,"errorMessage":"apiKeyFun.errors.queryFailed","messagePattern":"apiKeyFun\\.errors\\.queryFailed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/pages/ApiKeyFun.tsx","lineNumber":249,"sourceCode":"                            baseUrl: endpoint // optionally update baseUrl\n                        };\n                        return updated;\n                    } else {\n                        // Automatically save new key\n                        return [{\n                            id: crypto.randomUUID(),\n                            key,\n                            name: maskKey(key),\n                            baseUrl: endpoint,\n                            createdAt: now,\n                            lastUsedAt: now,\n                            lastStatus: 'ok',\n                            lastRemaining: usageSummary?.remaining\n                        }, ...prev];\n                    }\n                });\n            } else {\n                throw new Error(t('apiKeyFun.errors.queryFailed', { defaultValue: '无法获取有效的额度数据或模型列表，请确认 API Key 是否有效，以及接口地址是否正确。' }));\n            }\n\n        } catch (error: any) {\n            console.error('Balance query failed', error);\n            setQueryError(error?.message || 'Query failed. Please verify network or key validity.');\n            setManagedKeys(prev => {\n                const existingIndex = prev.findIndex(item => item.key === key);\n                const now = Date.now();\n                if (existingIndex >= 0) {\n                    const updated = [...prev];\n                    updated[existingIndex] = {\n                        ...updated[existingIndex],\n                        lastStatus: 'bad',\n                        lastUsedAt: now,\n                        baseUrl: endpoint\n                    };\n                    return updated;\n                } else {","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/lbjlaq/Antigravity-Manager/blob/90a2b6b20797e2e593a83d0c54ab86037863fe70/src/pages/ApiKeyFun.tsx#L231-L267","documentation":"ApiKeyFun's balance query throws this when, after fetching usage and model data, neither a valid quota/remaining value nor a model list could be obtained — i.e. the key/address did not yield usable data. The message is shown via setQueryError.","triggerScenarios":"Query completes without throwing but the parsed usage summary lacks balance/remaining data AND the model list is empty — e.g. wrong base URL, invalid API key returning 200 with an error body, or an unsupported provider shape.","commonSituations":"Typo in the API base URL (pointing at a non-OpenAI-compatible endpoint), revoked or mistyped API key, provider that returns 200 with an HTML/error payload.","solutions":["Verify the API key is valid and has quota by calling the provider directly (curl /v1/models)","Check the configured base URL matches the provider's OpenAI-compatible endpoint","Inspect network responses for 200-with-error bodies and surface them","Add a defaultValue fallback check before throwing so partial data (e.g. models only) is not discarded"],"exampleFix":"// before\nthrow new Error(t('apiKeyFun.errors.queryFailed', { defaultValue: '无法获取有效的额度数据...' }));\n// after\nif (usageSummary) { /* use partial result */ }\nelse throw new Error(t('apiKeyFun.errors.queryFailed', { defaultValue: '无法获取有效的额度数据或模型列表...' }));","handlingStrategy":"validation","validationCode":"const hasData = usageSummary?.remaining != null || (modelList && modelList.length > 0); if (!hasData) throw new Error('no valid quota/model data');","typeGuard":"const isValidUsage = (u: unknown): u is { remaining: number } => !!u && typeof (u as any).remaining === 'number';","tryCatchPattern":"try { await queryBalance(key); } catch (e) { setQueryError(e?.message); setManagedKeys(prev => prev.map(k => k.key === key ? { ...k, lastStatus: 'error' } : k)); }","preventionTips":["Verify keys with a cheap /v1/models call before full balance queries","Normalize provider response shapes before use","Validate base URL format before querying"],"tags":["api","query","api-key"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"90a2b6b20797e2e593a83d0c54ab86037863fe70","analyzedAt":"2026-09-19T08:34:01.322Z","contentChangedAt":"2026-09-19T08:34:01.322Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}