{"record":{"id":"351dd208c10c0a70","repo":"hsliuping/TradingAgents-CN","slug":"openai-custom-openai-api-key","errorCode":null,"errorMessage":"使用自定义OpenAI端点需要设置CUSTOM_OPENAI_API_KEY环境变量","messagePattern":"使用自定义OpenAI端点需要设置CUSTOM_OPENAI_API_KEY环境变量","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"tradingagents/graph/trading_graph.py","lineNumber":429,"sourceCode":"            self.deep_thinking_llm, self.quick_thinking_llm = _create_provider_pair(\n                provider=\"deepseek\",\n                config=self.config,\n                quick_temperature=quick_temperature,\n                quick_max_tokens=quick_max_tokens,\n                quick_timeout=quick_timeout,\n                deep_temperature=deep_temperature,\n                deep_max_tokens=deep_max_tokens,\n                deep_timeout=deep_timeout,\n                backend_url=deepseek_base_url,\n                api_key=deepseek_api_key,\n                quick_extra_kwargs=_quick_extra if _quick_extra else None,\n                deep_extra_kwargs=_deep_extra if _deep_extra else None,\n            )\n            logger.info(\"✅ [DeepSeek] 已通过 llm_clients 初始化成功并应用用户配置的模型参数\")\n        elif normalized_provider == \"custom_openai\":\n            custom_api_key = os.getenv('CUSTOM_OPENAI_API_KEY')\n            if not custom_api_key:\n                raise ValueError(\"使用自定义OpenAI端点需要设置CUSTOM_OPENAI_API_KEY环境变量\")\n\n            custom_base_url = self.config.get(\"custom_openai_base_url\", \"https://api.openai.com/v1\")\n            logger.info(f\"🔧 [自定义OpenAI] 使用端点: {custom_base_url}\")\n            self.deep_thinking_llm, self.quick_thinking_llm = _create_provider_pair(\n                provider=\"custom_openai\",\n                config=self.config,\n                quick_temperature=quick_temperature,\n                quick_max_tokens=quick_max_tokens,\n                quick_timeout=quick_timeout,\n                deep_temperature=deep_temperature,\n                deep_max_tokens=deep_max_tokens,\n                deep_timeout=deep_timeout,\n                backend_url=custom_base_url,\n                api_key=custom_api_key,\n                quick_extra_kwargs=_quick_extra if _quick_extra else None,\n                deep_extra_kwargs=_deep_extra if _deep_extra else None,\n            )\n            logger.info(\"✅ [自定义OpenAI] 已通过 llm_clients 初始化成功并应用用户配置的模型参数\")","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/hsliuping/TradingAgents-CN/blob/74783e8817d6cf6de29867880631cc555153f36b/tradingagents/graph/trading_graph.py#L411-L447","documentation":"TradingAgentsGraph.__init__ raises this for provider 'custom_openai' when the CUSTOM_OPENAI_API_KEY environment variable is unset. Note this branch reads only the environment — the key cannot come from DB config — while the base URL does come from config (custom_openai_base_url, defaulting to OpenAI's endpoint).","triggerScenarios":"llm_provider=\"custom_openai\" without CUSTOM_OPENAI_API_KEY exported, e.g. pointing at a self-hosted vLLM/LiteLLM endpoint that still requires auth.","commonSituations":"Using an OpenAI-compatible gateway (one-api, LiteLLM proxy) and forgetting its token; local vLLM with no auth where users expect to skip the key but the branch requires it; env var missing in service unit.","solutions":["export CUSTOM_OPENAI_API_KEY=<token-or-dummy> (some local servers accept any non-empty value)","Also set custom_openai_base_url in config to your endpoint if it differs from https://api.openai.com/v1","Persist the variable in .env/compose and load dotenv before graph init"],"exampleFix":"# before\ngraph = TradingAgentsGraph(config={\"llm_provider\": \"custom_openai\", \"custom_openai_base_url\": \"http://localhost:8000/v1\"})\n\n# after\n# export CUSTOM_OPENAI_API_KEY=local-token\ncfg = {\"llm_provider\": \"custom_openai\", \"custom_openai_base_url\": \"http://localhost:8000/v1\"}\ngraph = TradingAgentsGraph(config=cfg)","handlingStrategy":"validation","validationCode":"import os\nif provider == \"custom_openai\" and not os.getenv(\"CUSTOM_OPENAI_API_KEY\"):\n    raise SystemExit(\"Set CUSTOM_OPENAI_API_KEY (required even for local endpoints)\")","typeGuard":"def has_custom_openai_key() -> bool:\n    return bool(os.getenv(\"CUSTOM_OPENAI_API_KEY\"))","tryCatchPattern":"try:\n    graph = TradingAgentsGraph(config=cfg)\nexcept ValueError as e:\n    if \"CUSTOM_OPENAI_API_KEY\" in str(e):\n        os.environ[\"CUSTOM_OPENAI_API_KEY\"] = \"dummy\"  # only for auth-free local endpoints\n        graph = TradingAgentsGraph(config=cfg)\n    else:\n        raise","preventionTips":["Remember this branch reads env only — DB keys are ignored","Always set custom_openai_base_url alongside the key","Treat local no-auth servers as still needing a non-empty dummy token"],"tags":["api-key","missing-env-var","custom-endpoint","openai-compatible","llm"],"backgroundTag":"missing-api-key","analyzedSha":"74783e8817d6cf6de29867880631cc555153f36b","analyzedAt":"2026-08-28T11:39:07.729Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}