{"record":{"id":"6a934289e2fbecf2","repo":"zylon-ai/private-gpt","slug":"environment-variable-env-var-is-not-set-and-not","errorCode":null,"errorMessage":"Environment variable {env_var} is not set and not default was provided","messagePattern":"Environment variable (.+?) is not set and not default was provided","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"private_gpt/settings/yaml.py","lineNumber":36,"sourceCode":"    the value of the environment variable.\n    \"\"\"\n    loader = SafeLoader(stream)\n\n    def load_env_var(_, node) -> str:\n        \"\"\"Extract the matched value, expand env variable, and replace the match.\"\"\"\n        value = str(node.value).removeprefix(\"${\").removesuffix(\"}\")\n        split = value.split(\":\", 1)\n        env_vars = split[0].strip()\n        env_value: str | None = None\n        for env_var in env_vars.split(\",\"):\n            env_var = env_var.strip()\n            env_value = environ.get(env_var) or env_value\n            if env_value is not None:\n                break\n        value = env_value\n        default = None if len(split) == 1 else split[1]\n        if value is None and default is None:\n            raise ValueError(\n                f\"Environment variable {env_var} is not set and not default was provided\"\n            )\n        return value or default\n\n    loader.add_implicit_resolver(\"env_var_replacer\", _env_replace_matcher, None)\n    loader.add_constructor(\"env_var_replacer\", load_env_var)\n\n    try:\n        return loader.get_single_data()\n    finally:\n        loader.dispose()\n","sourceCodeStart":18,"sourceCodeEnd":48,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/settings/yaml.py#L18-L48","documentation":"Raised by the custom YAML loader (load_yaml_with_envvars) when a settings file contains an ${ENV_VAR} substitution (or a comma-separated candidate list like ${VAR_A,VAR_B}) and none of the referenced environment variables is set, and no default after a colon (${VAR:default}) was provided. The loader refuses to silently substitute empty values, so startup fails at YAML parse time.","triggerScenarios":"settings.yaml contains password: ${OPENAI_API_KEY} but the variable is unset in the shell/container; using ${DB_USER,DB_USERNAME} where neither is exported; forgetting the ':default' syntax when the value is optional; deploying with docker-compose/Kubernetes that does not pass the variable through (not listed in environment: or env_file).","commonSituations":"Works locally because the var is exported in the developer shell, then fails in CI or a container; renaming an environment variable without updating settings.yaml; sample settings files that reference vars the deployer never set; systemd/supervisor units that drop the user's environment.","solutions":["Export the missing variable in the environment where private-gpt starts (verify with: echo \"${VAR?unset}\")","Add a default in the YAML: change ${VAR} to ${VAR:fallback}","If multiple names are possible use the comma form: ${PRIMARY_VAR,FALLBACK_VAR}","For containers, ensure the variable is declared in compose 'environment:'/'env_file:' or the Kubernetes pod spec","If the setting is optional, consider removing the placeholder from settings.yaml entirely"],"exampleFix":"# settings.yaml - before\nllm:\n  api_key: ${OPENAI_API_KEY}\n\n# after (with default)\nllm:\n  api_key: ${OPENAI_API_KEY:dummy-key}\n# or: export OPENAI_API_KEY=sk-... before starting","handlingStrategy":"validation","validationCode":"import os, re\n\ndef check_env_placeholders(yaml_path: str) -> list[str]:\n    text = open(yaml_path).read()\n    missing = []\n    for m in re.finditer(r\"\\$\\{([^}]+)}\", text):\n        body = m.group(1)\n        names, _, default = body.partition(\":\")\n        if default:\n            continue\n        if not any(os.environ.get(n.strip()) for n in names.split(\",\")):\n            missing.append(names)\n    return missing  # non-empty => error 422 will occur","typeGuard":"null","tryCatchPattern":"try:\n    cfg = load_yaml_with_envvars(open(\"settings.yaml\"))\nexcept ValueError as e:\n    # e names the missing var; export it or add ':default' in the YAML\n    raise SystemExit(str(e)) from e","preventionTips":["Prefer ${VAR:default} in settings files whenever a sane fallback exists","Centralize required variables in one .env loaded by every entrypoint (dev, CI, containers)","Add a startup preflight that exports-and-checks each referenced variable","In compose files, declare every settings-referenced variable under environment: or env_file:"],"tags":["configuration","environment-variables","yaml","startup"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}