ZhuLinsen/daily_stock_analysis · error · ValueError

{field_name} must be one of: {allowed}

Error message

{field_name} must be one of: {allowed}

What it means

ValueError from the decision-profile normalizer when a supplied profile value is non-empty but not in VALID_DECISION_PROFILES. Profiles are a closed, lowercased enum (field_name defaults to 'decision_profile' and is used in the message); empty/None passes through as no profile, everything else must match exactly after strip+lower.

Source

Thrown at src/schemas/decision_profile.py:65

DECISION_PROFILE_FILTER_UNKNOWN = DecisionProfileFilter("unknown")


def normalize_decision_profile(
    value: Any,
    *,
    field_name: str = "decision_profile",
) -> Optional[DecisionProfile]:
    """Return a normalized profile or raise for a non-empty invalid value."""

    if value in (None, ""):
        return None
    text = str(value).strip().lower()
    if not text:
        return None
    if text in VALID_DECISION_PROFILES:
        return text  # type: ignore[return-value]
    allowed = ", ".join(VALID_DECISION_PROFILES)
    raise ValueError(f"{field_name} must be one of: {allowed}")


def normalize_decision_profile_filter(value: Any) -> DecisionProfileFilter:
    """Normalize list-filter input while preserving all-vs-unknown semantics."""

    if value in (None, ""):
        return DECISION_PROFILE_FILTER_ALL
    text = str(value).strip().lower()
    if not text:
        return DECISION_PROFILE_FILTER_ALL
    if text == DECISION_PROFILE_UNKNOWN:
        return DECISION_PROFILE_FILTER_UNKNOWN
    profile = normalize_decision_profile(text, field_name="decision_profile")
    return DecisionProfileFilter("profile", profile)


def extract_legacy_decision_profile(metadata: Any) -> Optional[DecisionProfile]:
    """Extract a legal legacy profile from metadata; invalid values are ignored."""

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Check the error message — it lists the allowed values verbatim; use one of those
  2. Fix typos and remove extra tokens; note normalization handles case and surrounding whitespace already
  3. On the client side, source profile names from the API's enumeration endpoint or constants instead of hardcoding strings
  4. After renames/upgrades, update stored user preferences or configs that reference retired profile names

Example fix

# before
GET /api/decisions?decision_profile=aggressive

# after
GET /api/decisions?decision_profile=<one of the values listed in the error>
Defensive patterns

Strategy: validation

Validate before calling

from src.schemas.decision_profile import VALID_DECISION_PROFILES

def is_valid_decision_profile(value: str) -> bool:
    return (value or "").strip().lower() in VALID_DECISION_PROFILES

Type guard

from typing import Any
from src.schemas.decision_profile import VALID_DECISION_PROFILES

def is_decision_profile(value: Any) -> bool:
    return isinstance(value, str) and value.strip().lower() in VALID_DECISION_PROFILES

Try / catch

try:
    profile = normalize_decision_profile(request.args.get("decision_profile"))
except ValueError as exc:
    return bad_request(str(exc))  # echoes allowed values

Prevention

When it happens

Trigger: Passing decision_profile='aggressive', 'steady', 'balanced ' (trailing junk), or any string not in the allowed set through a query param, API payload, or CLI flag. Normalization lowercases and strips, so the failure means the value is genuinely outside the enum, not a casing issue.

Common situations: API consumers guessing profile names; a renamed profile after an upgrade while old clients keep sending the previous value; typos; passing a profile filter value where a single profile is required.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/4fb2c52412aab561. Report an issue: GitHub.