{"record":{"id":"4d21097c031ec4be","repo":"FoundationAgents/MetaGPT","slug":"envkeynotfounderror-key-app-name-app-name-or","errorCode":null,"errorMessage":"EnvKeyNotFoundError: {key}, app_name:{app_name or ''}","messagePattern":"EnvKeyNotFoundError: (.+?), app_name:(.+?)","errorType":"exception","errorClass":"EnvKeyNotFoundError","httpStatus":null,"severity":"error","filePath":"metagpt/tools/libs/env.py","lineNumber":45,"sourceCode":"\n\nasync def default_get_env(key: str, app_name: str = None) -> str:\n    app_key = to_app_key(key=key, app_name=app_name)\n    if app_key in os.environ:\n        return os.environ[app_key]\n\n    env_app_key = app_key.replace(\"-\", \"_\")  # \"-\" is not supported by linux environment variable\n    if env_app_key in os.environ:\n        return os.environ[env_app_key]\n\n    from metagpt.context import Context\n\n    context = Context()\n    val = context.kwargs.get(app_key, None)\n    if val is not None:\n        return val\n\n    raise EnvKeyNotFoundError(f\"EnvKeyNotFoundError: {key}, app_name:{app_name or ''}\")\n\n\nasync def default_get_env_description() -> Dict[str, str]:\n    result = {}\n    for k in os.environ.keys():\n        app_name, key = split_app_key(k)\n        call = f'await get_env(key=\"{key}\", app_name=\"{app_name}\")'\n        result[call] = f\"Return the value of environment variable `{k}`.\"\n\n    from metagpt.context import Context\n\n    context = Context()\n    for k in context.kwargs.__dict__.keys():\n        app_name, key = split_app_key(k)\n        call = f'await get_env(key=\"{key}\", app_name=\"{app_name}\")'\n        result[call] = f\"Get the value of environment variable `{k}`.\"\n    return result\n","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/tools/libs/env.py#L27-L63","documentation":"EnvKeyNotFoundError from get_env in metagpt/tools/libs/env.py: the requested key was not found as an environment variable (with the app-name prefix, '-' replaced by '_') nor in the shared Context.kwargs mapping. It signals a missing configuration value, not a broken API call.","triggerScenarios":"await get_env(key='SERPER_API_KEY', app_name='metagpt') when neither METAGPT_SERPER_API_KEY-style env var exists nor context.kwargs contains the key under the app-qualified name.","commonSituations":"Forgot to export the variable or add it to .env; app_name/key mismatch so the composed env var name doesn't match what was set; running in a fresh shell/CI where secrets were never injected; the key exists under a different app namespace.","solutions":["Export the correctly prefixed variable: the tool derives it from app_name + key with '-' mapped to '_' (e.g. APPNAME_KEY)","Or put the value into Context kwargs under the app-qualified key","Inspect `await default_get_env_description()` to see the exact call/naming the tool expects"],"exampleFix":"# before\nval = await get_env(key=\"API_KEY\", app_name=\"my-app\")  # raises\n# after\nexport MY_APP_API_KEY=sk-...  # '-' becomes '_', prefixed by app name\nval = await get_env(key=\"API_KEY\", app_name=\"my-app\")","handlingStrategy":"validation","validationCode":"import os\nfrom metagpt.tools.libs.env import split_app_key\ncomposed = (app_name + \"_\" + key).replace(\"-\", \"_\") if app_name else key.replace(\"-\", \"_\")\nif composed not in os.environ and not Context().kwargs.get(f\"{app_name}_{key}\".replace(\"-\", \"_\") if app_name else key):\n    raise SystemExit(f\"missing env value: {composed}\")","typeGuard":null,"tryCatchPattern":"try:\n    val = await get_env(key=key, app_name=app_name)\nexcept EnvKeyNotFoundError:\n    val = default_value  # or prompt the user to configure","preventionTips":["Run `await default_get_env_description()` once to learn the exact expected names","Centralize secrets in .env / secret manager and load before startup","Remember '-' becomes '_' and app_name prefixes the variable"],"tags":["environment","config","secrets","env-vars"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}