{"record":{"id":"06f62085dbf93002","repo":"666ghj/MiroFish","slug":"llm-api-key","errorCode":null,"errorMessage":"LLM_API_KEY 未配置","messagePattern":"LLM_API_KEY 未配置","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"backend/app/services/oasis_profile_generator.py","lineNumber":256,"sourceCode":"    GROUP_ENTITY_TYPES = [\n        \"university\", \"governmentagency\", \"organization\", \"ngo\", \n        \"mediaoutlet\", \"company\", \"institution\", \"group\", \"community\"\n    ]\n    \n    def __init__(\n        self, \n        api_key: Optional[str] = None,\n        base_url: Optional[str] = None,\n        model_name: Optional[str] = None,\n        zep_api_key: Optional[str] = None,\n        graph_id: Optional[str] = None\n    ):\n        self.api_key = api_key or Config.LLM_API_KEY\n        self.base_url = base_url or Config.LLM_BASE_URL\n        self.model_name = model_name or Config.LLM_MODEL_NAME\n        \n        if not self.api_key:\n            raise ValueError(\"LLM_API_KEY 未配置\")\n        \n        self.client = OpenAI(\n            api_key=self.api_key,\n            base_url=self.base_url\n        )\n        \n        # Zep客户端用于检索丰富上下文\n        self.zep_api_key = zep_api_key or Config.ZEP_API_KEY\n        self.zep_client = None\n        self.graph_id = graph_id\n        \n        if self.zep_api_key:\n            try:\n                self.zep_client = get_zep_client(self.zep_api_key)\n            except Exception as e:\n                logger.warning(f\"Zep客户端初始化失败: {e}\")\n    \n    def generate_profile_from_entity(","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/backend/app/services/oasis_profile_generator.py#L238-L274","documentation":"Raised in OasisProfileGenerator.__init__: the constructor takes an optional api_key but falls back to Config.LLM_API_KEY, and if both are empty it raises ValueError('LLM_API_KEY 未配置') before constructing the OpenAI client. This is a bootstrap-time configuration check — the LLM client for profile generation cannot be created without credentials.","triggerScenarios":"Instantiating OasisProfileGenerator (directly or via the profile-generation flow) when the LLM_API_KEY environment variable is unset/empty and no api_key argument is passed. Common in fresh deployments, CI, or containers that don't load the .env file.","commonSituations":"Missing entry in .env / docker-compose environment; backend started without loading dotenv; typo in the variable name (LLM_APIKEY, LLM_KEY); deploying to a new environment and forgetting to port secrets; running tests that construct the service without patching Config.","solutions":["Set LLM_API_KEY in the backend environment (.env, docker-compose environment block, or export) and restart.","Or pass api_key explicitly when constructing OasisProfileGenerator.","Verify the key name matches Config.LLM_API_KEY exactly and that the env file is actually loaded where the process starts.","For tests, patch Config.LLM_API_KEY or inject a dummy key so construction succeeds."],"exampleFix":"# before\ngen = OasisProfileGenerator()  # ValueError: LLM_API_KEY 未配置\n# after\n# .env\nLLM_API_KEY=sk-...\nLLM_BASE_URL=https://api.example.com/v1\ngen = OasisProfileGenerator()","handlingStrategy":"validation","validationCode":"from app.config import Config\nassert Config.LLM_API_KEY, 'LLM_API_KEY missing: set it in .env before starting the backend'","typeGuard":null,"tryCatchPattern":"try:\n    gen = OasisProfileGenerator()\nexcept ValueError as e:\n    if 'LLM_API_KEY' in str(e):\n        raise SystemExit('Configure LLM_API_KEY in the environment and restart') from e\n    raise","preventionTips":["Fail fast at process startup: validate required env vars before serving requests.","Keep a template .env.example listing LLM_API_KEY, LLM_BASE_URL, LLM_MODEL_NAME.","In CI/tests, patch Config.LLM_API_KEY with a dummy value."],"tags":["config","llm","api-key","openai","environment"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}