zylon-ai/private-gpt · error · ValueError
Invalid status: {value}. Valid options: {[s.value for s in c
Error message
Invalid status: {value}. Valid options: {[s.value for s in cls]} What it means
Raised by StreamStatus.from_string when the supplied value, after lowercasing and stripping, does not match any StreamStatus enum member value. The parser is intentionally strict — it lists the accepted values in the message — because status strings drive stream lifecycle logic. It is the standard boundary validator for converting external strings (API payloads, DB rows, env vars) into the enum.
Source
Thrown at private_gpt/components/streaming/providers/models.py:67
if not isinstance(other, StreamStatus):
return NotImplemented
return self._get_order() >= other._get_order()
def __hash__(self) -> int:
return hash(self.value)
def __str__(self) -> str:
"""Return the string representation of the status."""
return self.value
@classmethod
def from_string(cls, value: str) -> "StreamStatus":
"""Create StreamStatus from string value."""
normalized = str(value).lower().strip()
for status in cls:
if status.value == normalized:
return status
raise ValueError(
f"Invalid status: {value}. Valid options: {[s.value for s in cls]}"
)
class StreamMetadata(BaseModel):
correlation_id: str = Field(
default_factory=lambda: str(uuid.uuid4()),
description="Unique identifier for the stream",
)
status: StreamStatus = Field(
default=StreamStatus.PENDING,
description="Current status of the stream",
)
created_at: datetime = Field(
default=datetime.now(UTC),
description="Timestamp when the stream was created",
)
updated_at: datetime = Field(View on GitHub (pinned to 4a030776a3)
Solutions
- Use only the enum values printed in the error message, e.g. StreamStatus.from_string("completed")
- Pre-validate external input against {s.value for s in StreamStatus} and reject early with a clear 400 response
- After upgrades, migrate stored status strings or add a mapping layer from legacy names to current enum values
Example fix
# before
status = StreamStatus.from_string(request_body["status"]) # "done" -> ValueError
# after
VALID = {s.value for s in StreamStatus}
raw = request_body["status"].lower().strip()
if raw not in VALID:
raise HTTPException(400, f"status must be one of {sorted(VALID)}")
status = StreamStatus.from_string(raw) Defensive patterns
Strategy: type-guard
Validate before calling
from private_gpt.components.streaming.providers.models import StreamStatus
VALID_STATUSES = {s.value for s in StreamStatus}
raw = value.lower().strip()
if raw not in VALID_STATUSES:
raise ValueError(f"status must be one of {sorted(VALID_STATUSES)}, got {value!r}")
status = StreamStatus.from_string(raw) Type guard
def is_valid_stream_status(value: str) -> bool:
normalized = value.lower().strip()
return normalized in {s.value for s in StreamStatus} Try / catch
try:
status = StreamStatus.from_string(raw)
except ValueError:
status = StreamStatus.PENDING # explicit default, not a silent fallback of data Prevention
- Validate status strings at the API boundary with the enum-derived set
- Add a mapping table for legacy status names after upgrades
When it happens
Trigger: Calling StreamStatus.from_string with values like "finished", "done", "Success" with trailing punctuation, or an empty string. Also raised when deserializing a status persisted by an older version whose vocabulary changed.
Common situations: Client sends a status name not in the enum; a renamed enum value across versions invalidates stored data; case/whitespace variants that strip/lower cannot normalize (e.g. "IN_PROGRESS " is fine but "in-progress" is not).
Related errors
- Unknown reasoning effort level: {effort_str}
- Invalid ToolValidationMode: {mode_str}
- Stream with this message_id already exists
- Invalid system specification (dict): {system}
- Invalid system item in list (dict): {item}
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/ea420624fe3633ad.
Report an issue: GitHub.