{"record":{"id":"9d93233d73f995cd","repo":"FoundationAgents/MetaGPT","slug":"please-set-your-api-key-in-config2-yaml","errorCode":null,"errorMessage":"Please set your API key in config2.yaml","messagePattern":"Please set your API key in config2\\.yaml","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"metagpt/configs/llm_config.py","lineNumber":130,"sourceCode":"    # reasoning / thinking switch\n    reasoning: bool = False\n    reasoning_max_token: int = 4000  # reasoning budget tokens to generate, usually smaller than max_token\n\n    @field_validator(\"api_key\")\n    @classmethod\n    def check_llm_key(cls, v):\n        if v in [\"\", None, \"YOUR_API_KEY\"]:\n            repo_config_path = METAGPT_ROOT / \"config/config2.yaml\"\n            root_config_path = CONFIG_ROOT / \"config2.yaml\"\n            if root_config_path.exists():\n                raise ValueError(\n                    f\"Please set your API key in {root_config_path}. If you also set your config in {repo_config_path}, \\n\"\n                    f\"the former will overwrite the latter. This may cause unexpected result.\\n\"\n                )\n            elif repo_config_path.exists():\n                raise ValueError(f\"Please set your API key in {repo_config_path}\")\n            else:\n                raise ValueError(\"Please set your API key in config2.yaml\")\n        return v\n\n    @field_validator(\"timeout\")\n    @classmethod\n    def check_timeout(cls, v):\n        return v or LLM_API_TIMEOUT\n","sourceCodeStart":112,"sourceCodeEnd":137,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/configs/llm_config.py#L112-L137","documentation":"The fallback branch of LLMConfig.check_llm_key: the api_key is empty/placeholder and neither the root config (~/.metagpt/config2.yaml) nor the repo config (metagpt/config/config2.yaml) exists at all, so the validator has no file to point at and tells you to create config2.yaml. Any LLM construction will fail until a config with a valid key is provided.","triggerScenarios":"Running any LLM call in an environment where config2.yaml was never created (no template copied, no user config), and no api_key supplied via code or environment.","commonSituations":"New installs where the setup step (copying config2.yaml) was skipped; Docker/CI images that never bake a config; library usage where the caller assumed defaults work without a key.","solutions":["Copy the template: cp metagpt/config/config2.yaml ~/.metagpt/config2.yaml (or keep it in-repo) and set api_key.","Or construct config in code: LLM.from_llm_config(LLMConfig(api_key='sk-...', base_url=..., model=...)).","In CI, write the config from a secret env var before starting MetaGPT."],"exampleFix":"# before\nfrom metagpt.llm import LLM\nllm = LLM()  # ValueError: Please set your API key in config2.yaml\n\n# after\nfrom metagpt.configs.llm_config import LLMConfig\nllm = LLM(LLMConfig(api_key='sk-...', model='gpt-4o-mini'))","handlingStrategy":"validation","validationCode":"import os\nassert os.environ.get('OPENAI_API_KEY'), 'set OPENAI_API_KEY or create config2.yaml'\n# then either export the env var your provider block reads, or write the config:\n# ~/.metagpt/config2.yaml with a valid api_key","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run the documented setup to copy config2.yaml and fill api_key.","In CI, generate the config file from a secret before tests.","Pass LLMConfig explicitly when embedding MetaGPT in another app."],"tags":["config","api-key","llm","setup"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}