zylon-ai/private-gpt · critical · ValueError
Environment variable {env_var} is not set and not default wa
Error message
Environment variable {env_var} is not set and not default was provided What it means
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.
Source
Thrown at private_gpt/settings/yaml.py:36
the value of the environment variable.
"""
loader = SafeLoader(stream)
def load_env_var(_, node) -> str:
"""Extract the matched value, expand env variable, and replace the match."""
value = str(node.value).removeprefix("${").removesuffix("}")
split = value.split(":", 1)
env_vars = split[0].strip()
env_value: str | None = None
for env_var in env_vars.split(","):
env_var = env_var.strip()
env_value = environ.get(env_var) or env_value
if env_value is not None:
break
value = env_value
default = None if len(split) == 1 else split[1]
if value is None and default is None:
raise ValueError(
f"Environment variable {env_var} is not set and not default was provided"
)
return value or default
loader.add_implicit_resolver("env_var_replacer", _env_replace_matcher, None)
loader.add_constructor("env_var_replacer", load_env_var)
try:
return loader.get_single_data()
finally:
loader.dispose()
View on GitHub (pinned to 4a030776a3)
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
Example fix
# settings.yaml - before
llm:
api_key: ${OPENAI_API_KEY}
# after (with default)
llm:
api_key: ${OPENAI_API_KEY:dummy-key}
# or: export OPENAI_API_KEY=sk-... before starting Defensive patterns
Strategy: validation
Validate before calling
import os, re
def check_env_placeholders(yaml_path: str) -> list[str]:
text = open(yaml_path).read()
missing = []
for m in re.finditer(r"\$\{([^}]+)}", text):
body = m.group(1)
names, _, default = body.partition(":")
if default:
continue
if not any(os.environ.get(n.strip()) for n in names.split(",")):
missing.append(names)
return missing # non-empty => error 422 will occur Type guard
null
Try / catch
try:
cfg = load_yaml_with_envvars(open("settings.yaml"))
except ValueError as e:
# e names the missing var; export it or add ':default' in the YAML
raise SystemExit(str(e)) from e Prevention
- 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:
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Default model '{self._default_model_id}' not found in regist
- Config file has no top-level mapping: {path}
- Settings file not found for profile '{profile}'. Searched in
- PGPT_WORKER_MODE is required
- Default LLM model '{model_id}' could not be initialized: {e}
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/6a934289e2fbecf2.
Report an issue: GitHub.