{"record":{"id":"7ef8f29f1acd8c81","repo":"linshenkx/prompt-optimizer","slug":"cross-origin-connection-failed-error-message","errorCode":null,"errorMessage":"Cross-origin connection failed: ${error.message}","messagePattern":"Cross-origin connection failed: (.+?)","errorType":"exception","errorClass":"APIError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/llm/adapters/openai-adapter.ts","lineNumber":175,"sourceCode":"\n        if (models.length === 0) {\n          throw new APIError('API returned empty model list')\n        }\n\n        return models\n      }\n\n      throw new APIError('Unexpected API response format')\n    } catch (error: any) {\n      console.error('[OpenAIAdapter] Failed to fetch models:', error)\n\n      // 连接错误处理（包括跨域检测）\n      if (error.message && (error.message.includes('Failed to fetch') ||\n          error.message.includes('Connection error'))) {\n        const isCrossOriginError = this.detectCrossOriginError(error, baseURL)\n\n        if (isCrossOriginError) {\n          throw new APIError(`Cross-origin connection failed: ${error.message}`)\n        } else {\n          throw new APIError(`Connection failed: ${error.message}`)\n        }\n      }\n\n      // API返回的错误信息\n      if (error.response?.data) {\n        throw new APIError(`API error: ${JSON.stringify(error.response.data)}`)\n      }\n\n      // 其他错误,保持原始信息\n      throw new APIError(error.message || 'Unknown error')\n    }\n  }\n\n  // ===== 参数定义（用于buildDefaultModel） =====\n\n  /**","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/llm/adapters/openai-adapter.ts#L157-L193","documentation":"During model listing the fetch failed with 'Failed to fetch' or 'Connection error', and detectCrossOriginError determined the failure is CORS-related (browser blocked a cross-origin request). The original message is wrapped with the 'Cross-origin connection failed:' prefix.","triggerScenarios":"Running the app in a browser and calling an OpenAI-compatible endpoint on another origin that doesn't return Access-Control-Allow-Origin — typical for local gateways (localhost:11434, :8000) accessed from a dev server on another port.","commonSituations":"Ollama/vLLM/llama.cpp called from a web app without CORS enabled, missing CORS middleware on a custom proxy, gateway allowing only certain origins.","solutions":["Enable CORS on the target server (e.g. OLLAMA_ORIGINS=* for Ollama; CORS middleware on FastAPI/nginx)","Or proxy requests through your own backend so the browser call is same-origin","Verify scheme/port/hostname exactly match the allowed origins","For production, never call provider APIs with secret keys directly from the browser"],"exampleFix":"# before (ollama blocks browser origin)\n# browser console: Cross-origin connection failed: Failed to fetch\n\n# after\nOllama: OLLAMA_ORIGINS=http://localhost:5173 ollama serve\n# or route via backend proxy /api/llm -> target","handlingStrategy":"fallback","validationCode":"// test CORS before first real call\nfetch(endpoint, { method: 'OPTIONS', mode: 'cors' }).catch(() => flagEndpointAsCorsBlocked(endpoint))","typeGuard":"function isCorsError(e: unknown): boolean {\n  return e instanceof APIError && e.message.startsWith('Cross-origin connection failed')\n}","tryCatchPattern":"try { models = await adapter.getModelsAsync() }\ncatch (e) {\n  if (isCorsError(e)) { instructUserToEnableCors(); models = [] }\n  else throw e\n}","preventionTips":["Enable CORS on gateways (OLLAMA_ORIGINS, nginx headers)","Proxy cross-origin LLM calls through your backend","Never embed provider API keys in browser code"],"tags":["cors","openai","browser","network"],"backgroundTag":"cors-request-blocked","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}