{"record":{"id":"15943908cf124833","repo":"datawhalechina/hello-agents","slug":"api-key-env-amap-api-key","errorCode":null,"errorMessage":"高德地图API Key未配置,请在.env文件中设置AMAP_API_KEY","messagePattern":"高德地图API Key未配置,请在\\.env文件中设置AMAP_API_KEY","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"code/chapter13/helloagents-trip-planner/backend/app/services/amap_service.py","lineNumber":25,"sourceCode":"\n# 全局MCP工具实例\n_amap_mcp_tool = None\n\n\ndef get_amap_mcp_tool() -> MCPTool:\n    \"\"\"\n    获取高德地图MCP工具实例(单例模式)\n    \n    Returns:\n        MCPTool实例\n    \"\"\"\n    global _amap_mcp_tool\n    \n    if _amap_mcp_tool is None:\n        settings = get_settings()\n        \n        if not settings.amap_api_key:\n            raise ValueError(\"高德地图API Key未配置,请在.env文件中设置AMAP_API_KEY\")\n        \n        # 创建MCP工具\n        _amap_mcp_tool = MCPTool(\n            name=\"amap\",\n            description=\"高德地图服务,支持POI搜索、路线规划、天气查询等功能\",\n            server_command=[\"uvx\", \"amap-mcp-server\"],\n            env={\"AMAP_MAPS_API_KEY\": settings.amap_api_key},\n            auto_expand=True  # 自动展开为独立工具\n        )\n        \n        print(f\"✅ 高德地图MCP工具初始化成功\")\n        print(f\"   工具数量: {len(_amap_mcp_tool._available_tools)}\")\n        \n        # 打印可用工具列表\n        if _amap_mcp_tool._available_tools:\n            print(\"   可用工具:\")\n            for tool in _amap_mcp_tool._available_tools[:5]:  # 只打印前5个\n                print(f\"     - {tool.get('name', 'unknown')}\")","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/code/chapter13/helloagents-trip-planner/backend/app/services/amap_service.py#L7-L43","documentation":"ValueError raised by get_amap_mcp_tool() (chapter13 amap_service.py) on first initialization when settings.amap_api_key is falsy. It guards creation of the MCPTool that shells out to `uvx amap-mcp-server`; without a key the subprocess would be useless, so init fails fast. The singleton means this fires once per process on first map usage.","triggerScenarios":"First call to any map/poi route or /map/health after booting without AMAP_API_KEY; key present but empty string; .env exists but was never loaded into settings.","commonSituations":"Same cluster as error 316 but surfacing lazily at first use instead of at startup — happens when code paths bypass the eager config validation; env var name mismatch after deployment changes.","solutions":["Set AMAP_API_KEY in backend/.env and restart the backend","Confirm the Settings object actually loads .env (check get_settings() source path and that the process cwd is right)","If it persists, print settings source or keys list (names only) to verify the variable is visible","Keep the eager config check enabled so this error surfaces at boot rather than mid-request"],"exampleFix":"# before\n# .env absent -> first map request raises ValueError\n\n# after\n# backend/.env\nAMAP_API_KEY=xxxx\n# then restart: uvicorn app.main:app --reload","handlingStrategy":"validation","validationCode":"import os\n\ndef amap_ready() -> bool:\n    key = os.getenv('AMAP_API_KEY', '')\n    return bool(key.strip())\n\nassert amap_ready(), 'AMAP_API_KEY missing — set it in backend/.env before using map features'","typeGuard":null,"tryCatchPattern":"try:\n    tool = get_amap_mcp_tool()\nexcept ValueError as e:\n    if 'AMAP_API_KEY' in str(e):\n        raise SystemExit('Configure AMAP_API_KEY and restart the backend')\n    raise","preventionTips":["Keep the eager startup config check enabled so this never surfaces lazily at request time","Verify settings actually load .env (cwd, dotenv path) in deployment scripts","Add a startup warm-up that touches get_amap_mcp_tool() to force early failure"],"tags":["configuration","amap","mcp","lazy-init"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}