ruvnet/RuView · error · ValueError
Log level must be one of: {allowed_levels}
Error message
Log level must be one of: {allowed_levels} What it means
Pydantic v2 @field_validator on Settings.log_level in archive/v1/src/config/settings.py. It uppercases the input and enforces membership in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']. The check is case-insensitive (v.upper()), but aliases are not supported: 'TRACE', 'NOTICE', 'VERBOSE', and notably 'WARN' — a legal alias in Python's own logging module — are all rejected with this ValueError at Settings() construction.
Source
Thrown at archive/v1/src/config/settings.py:191
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 v
@field_validator("stream_fps")
@classmethod
def validate_stream_fps(cls, v):
"""Validate streaming FPS."""
if not 1 <= v <= 60:
raise ValueError("Stream FPS must be between 1 and 60")
return v
View on GitHub (pinned to 4685618388)
Solutions
- Use the full standard names: DEBUG, INFO, WARNING, ERROR, or CRITICAL (case does not matter)
- Replace WARN with WARNING everywhere (docker-compose, .env, k8s env blocks)
- Map exotic levels at the source: TRACE->DEBUG, NOTICE->INFO
- Add a startup config check in CI to catch bad LOG_LEVEL values before deploy
Example fix
# before LOG_LEVEL=WARN # after LOG_LEVEL=WARNING
Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}
raw = os.environ.get("LOG_LEVEL", "INFO").strip().upper()
normalized = {"WARN": "WARNING", "TRACE": "DEBUG", "VERBOSE": "DEBUG", "NOTICE": "INFO"}.get(raw, raw)
assert normalized in ALLOWED, f"LOG_LEVEL must be one of {sorted(ALLOWED)}, got {raw!r}" Type guard
def is_valid_log_level(v: str) -> bool:
return v.strip().upper() in {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"} Try / catch
from pydantic import ValidationError
try:
settings = Settings()
except ValidationError as e:
if any(err["loc"][-1] == "log_level" for err in e.errors()):
raise SystemExit("LOG_LEVEL: use DEBUG|INFO|WARNING|ERROR|CRITICAL (WARN alias is rejected)") from e
raise Prevention
- Replace WARN with WARNING everywhere — the validator does not accept the stdlib alias
- Map non-stdlib levels (TRACE, NOTICE) to their nearest allowed value at the source
- Centralize logging config in one template so aliases cannot leak in from copy-paste
When it happens
Trigger: LOG_LEVEL=WARN (legal in logging.basicConfig but rejected here); LOG_LEVEL=TRACE or VERBOSE from structured-logging conventions; LOG_LEVEL=notice; lowercase 'debug' works (uppercased), but any non-standard name fails.
Common situations: Copying LOG_LEVEL=WARN from systemd or logging tutorials; switching from loguru (TRACE) back to stdlib settings; operators shortening WARNING to WARN in .env files.
Related errors
- Environment must be one of: {allowed_environments}
- 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/2e7f004343acebf7.
Report an issue: GitHub.