binary-husky/gpt_academic · error · KeyError

[ENV_VAR] 环境变量{arg}加载失败!

Error message

[ENV_VAR] 环境变量{arg}加载失败! 

What it means

shared_utils/config_loader.read_env_variable converts an environment variable to the type of the config default (str/int/bool/dict/list via eval); the whole body is wrapped in try/except that, on any failure — unsupported type, eval syntax error, int('abc') — logs '[ENV_VAR] 环境变量{arg}加载失败!' and raises KeyError. The bare except hides the actual conversion error.

Source

Thrown at shared_utils/config_loader.py:58

        elif isinstance(default_value, int):
            r = int(env_arg)
        elif isinstance(default_value, float):
            r = float(env_arg)
        elif isinstance(default_value, str):
            r = env_arg.strip()
        elif isinstance(default_value, dict):
            r = eval(env_arg)
        elif isinstance(default_value, list):
            r = eval(env_arg)
        elif default_value is None:
            assert arg == "proxies"
            r = eval(env_arg)
        else:
            log亮红(f"[ENV_VAR] 环境变量{arg}不支持通过环境变量设置! ")
            raise KeyError
    except:
        log亮红(f"[ENV_VAR] 环境变量{arg}加载失败! ")
        raise KeyError(f"[ENV_VAR] 环境变量{arg}加载失败! ")

    log亮绿(f"[ENV_VAR] 成功读取环境变量{arg}")
    return r


@lru_cache(maxsize=128)
def read_single_conf_with_lru_cache(arg):
    from shared_utils.key_pattern_manager import is_any_api_key
    try:
        # 优先级1. 获取环境变量作为配置
        default_ref = getattr(importlib.import_module('config'), arg) # 读取默认值作为数据类型转换的参考
        r = read_env_variable(arg, default_ref)
    except:
        try:
            # 优先级2. 获取config_private中的配置
            r = getattr(importlib.import_module('config_private'), arg)
        except:
            # 优先级3. 获取config中的配置

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Fix the env var value to be a valid Python literal of the same type as the config default (dict/list use Python literal syntax, not JSON, e.g. "{'k': 'v'}").
  2. Check the log亮红 line above the raise to identify which env var (arg) failed.
  3. Remove the env var and set the value directly in config.py instead.
  4. For bools use True/False, for ints plain digits, matching Python semantics.

Example fix

# before
export GPT_SOVITS_URL='{"url": "x"}'   # JSON braces -> eval fails

# after
export GPT_SOVITS_URL="'http://127.0.0.1:9880/'"  # valid Python literal
Defensive patterns

Strategy: validation

Validate before calling

import os, ast
def env_literal_ok(name: str, default) -> bool:
    v = os.environ.get(name)
    if v is None:
        return True
    try:
        if isinstance(default, (dict, list)) or default is None:
            ast.literal_eval(v)
        elif isinstance(default, bool):
            assert v in ('True', 'False')
        elif isinstance(default, int):
            int(v)
        return True
    except Exception:
        return False

if not env_literal_ok('MY_SETTING', default_ref):
    raise ConfigError('env var MY_SETTING is not a valid literal for its type')

Try / catch

try:
    val = read_single_conf_with_lru_cache('MY_SETTING')
except KeyError as e:
    if '环境变量' in str(e):
        show_env_syntax_help(arg='MY_SETTING')  # needs Python literal, not JSON

Prevention

When it happens

Trigger: Setting an environment variable for a config entry whose default is a dict/list and passing invalid Python literal syntax; a non-numeric string for an int default; a bad bool literal; or the env value being eval'd failing for any other reason during startup.

Common situations: Docker/k8s deployments passing config via env vars with JSON instead of Python-literal syntax (quotes/brackets mismatched); env var containing shell-expanded characters that break eval; typos like DEFAULT='none' for bool configs.

Related errors


AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14). Data as JSON: /api/errors/43d003ac81fca646. Report an issue: GitHub.