ruvnet/RuView · error · ValueError
Environment must be one of: {allowed_environments}
Error message
Environment must be one of: {allowed_environments} What it means
Pydantic v2 @field_validator on Settings.environment in archive/v1/src/config/settings.py. It enforces exact membership in ['development', 'staging', 'production'] — a case-sensitive check with no .lower() normalization, so 'Production', 'prod', 'dev', and 'test' are all rejected. Because this is a pydantic-settings class, the value typically arrives from the ENVIRONMENT env var, and an invalid value fails at Settings() construction, usually at application startup.
Source
Thrown at archive/v1/src/config/settings.py:182
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
# Tolerate `.env` keys that this Settings model doesn't declare
# (e.g., NPM_TOKEN, DOCKER_HUB_TOKEN, PYPI_TOKEN used by other
# tooling). Without `extra="ignore"` pydantic-settings 2.x
# raises `ValidationError: Extra inputs are not permitted` and
# leaks the offending values into the error message — a real
# security concern for secret tokens. See verify.py / `./verify`.
extra="ignore",
)
@field_validator("environment")
@classmethod
def validate_environment(cls, v):
"""Validate environment setting."""
allowed_environments = ["development", "staging", "production"]
if v not in allowed_environments:
raise ValueError(f"Environment must be one of: {allowed_environments}")
return v
@field_validator("log_level")
@classmethod
def validate_log_level(cls, v):
"""Validate log level setting."""
allowed_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
if v.upper() not in allowed_levels:
raise ValueError(f"Log level must be one of: {allowed_levels}")
return v.upper()
@field_validator("pose_confidence_threshold")
@classmethod
def validate_confidence_threshold(cls, v):
"""Validate confidence threshold."""
if not 0.0 <= v <= 1.0:
raise ValueError("Confidence threshold must be between 0.0 and 1.0")
return vView on GitHub (pinned to 4685618388)
Solutions
- Set ENVIRONMENT to the exact lowercase full word: development, staging, or production
- Strip whitespace and avoid inline comments on the ENVIRONMENT line in .env files
- Normalize in a wrapper if you must accept shorthand (env = {'dev': 'development', 'prod': 'production'}.get(raw, raw))
- If you genuinely need a new environment like 'ci', add it to allowed_environments in the validator
Example fix
# before ENVIRONMENT=prod # after ENVIRONMENT=production
Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = {"development", "staging", "production"}
raw = os.environ.get("ENVIRONMENT", "development").strip().lower()
environment = {"dev": "development", "prod": "production", "staging": "staging"}.get(raw, raw)
assert environment in ALLOWED, f"ENVIRONMENT must be one of {sorted(ALLOWED)}, got {raw!r}" Type guard
def is_valid_environment(v: str) -> bool:
return v in {"development", "staging", "production"} Try / catch
from pydantic import ValidationError
try:
settings = Settings()
except ValidationError as e:
if any(err["loc"][-1] == "environment" for err in e.errors()):
raise SystemExit("ENVIRONMENT must be exactly development|staging|production (lowercase, no shorthand)") from e
raise Prevention
- Use exact lowercase full words in ENVIRONMENT; the validator is case-sensitive
- Normalize shorthand (dev/prod) and whitespace in deployment scripts before the app reads them
- Add new environment names to the validator allow-list deliberately, with a PR
When it happens
Trigger: ENVIRONMENT=dev, ENVIRONMENT=prod, or ENVIRONMENT=test (common shorthand); ENVIRONMENT=Production (capitalized — rejected by the case-sensitive comparison); trailing whitespace like 'production ' from .env files; CI setting ENVIRONMENT=ci.
Common situations: Copying shorthand values from docker-compose or Makefiles of other projects; capitalized values in .env files; whitespace introduced by 'KEY=value # comment' parsing; new environments (ci, local, qa) not being added to the allow-list.
Related errors
- Log level must be one of: {allowed_levels}
- Confidence threshold must be between 0.0 and 1.0
- Stream FPS must be between 1 and 60
- Port must be between 1 and 65535
- Workers must be at least 1
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/8bdd3f32cfd7dc9c.
Report an issue: GitHub.