zylon-ai/private-gpt · error · ValueError
Unknown reasoning effort level: {effort_str}
Error message
Unknown reasoning effort level: {effort_str} What it means
ValueError from ReasoningEffort.from_str: the lowercased input string is not one of the enum's values (none, low, medium, high, max, xhigh). The enum is the closed vocabulary for reasoning effort across the library; any other string is rejected rather than guessed.
Source
Thrown at private_gpt/components/llm/models.py:17
import enum
class ReasoningEffort(enum.StrEnum):
NONE = "none"
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
MAX = "max"
XHIGH = "xhigh"
@classmethod
def from_str(cls, effort_str: str) -> "ReasoningEffort":
effort_str = effort_str.lower()
if effort_str in cls._value2member_map_:
return cls(effort_str)
raise ValueError(f"Unknown reasoning effort level: {effort_str}")
@property
def is_thinking_enabled(self) -> bool:
return self != ReasoningEffort.NONE
def normalize_reasoning_effort(
reasoning_effort: ReasoningEffort | str | None,
) -> ReasoningEffort:
"""Normalize values crossing untyped or serialized LLM boundaries."""
if reasoning_effort is None:
return ReasoningEffort.NONE
if isinstance(reasoning_effort, ReasoningEffort):
return reasoning_effort
if isinstance(reasoning_effort, str):
return ReasoningEffort.from_str(reasoning_effort)
raise TypeError(
"reasoning_effort must be a ReasoningEffort, string, or None; "View on GitHub (pinned to 4a030776a3)
Solutions
- Use one of the exact values: none, low, medium, high, max, xhigh (any case; it is lowercased).
- If 'off'/'disabled' was intended, use 'none'.
- Validate free-text effort settings against this list at config-load time to fail with a clearer message.
Example fix
# before reasoning_effort: aggressive # after reasoning_effort: high
Defensive patterns
Strategy: type-guard
Validate before calling
VALID_EFFORTS = {"none", "low", "medium", "high", "max", "xhigh"}
def effort_is_valid(s: str) -> bool:
return s.lower() in VALID_EFFORTS Type guard
from private_gpt.components.llm.models import ReasoningEffort
def is_reasoning_effort_str(value: object) -> bool:
return isinstance(value, str) and value.lower() in ReasoningEffort._value2member_map_ Try / catch
try:
effort = ReasoningEffort.from_str(raw)
except ValueError:
log.warning('Unknown reasoning effort %r; defaulting to none', raw)
effort = ReasoningEffort.NONE Prevention
- Declare reasoning_effort as an Enum field in settings/request models so invalid values fail at parse time.
- Offer only the documented levels in UI dropdowns and API docs.
- Map other vendors' effort labels to this enum at the integration boundary.
When it happens
Trigger: Calling from_str with e.g. "OFF", "ultra", "minimal", or a config/env value like 'reasoning_effort: aggressive'; also case is handled (it lowercases) but unknown words are not.
Common situations: Hand-written settings.yaml with an unsupported effort word; values from another provider's API (e.g. OpenAI's 'medium'/'high' subset works, but other vendors' labels like 'aggressive' do not); stale configs from versions before 'max'/'xhigh' existed or after a level was renamed.
Related errors
- Invalid ToolValidationMode: {mode_str}
- TOOL_NAME_CONFLICT
- Invalid reasoning_effort budget: {budget}. Must be a number
- LLM mode '{mode}' is not supported. Available: {available}
- No model specified and no models are configured
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/07f9d27f2fa06701.
Report an issue: GitHub.