zylon-ai/private-gpt · error · ValueError

Invalid status: . Valid options

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.

Solutions

  1. Use only the enum values printed in the error message, e.g. StreamStatus.from_string("completed")
  2. Pre-validate external input against {s.value for s in StreamStatus} and reject early with a clear 400 response
  3. 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

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


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/ea420624fe3633ad. Report an issue: GitHub.

Appendix: 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)