datawhalechina/hello-agents · warning · MovieServiceError

搜索关键词 q 不能为空

Error message

搜索关键词 q 不能为空

What it means

MovieServiceError with status_code=400 raised by search when the query string is empty after stripping. The service refuses to call TMDB's /search/movie with an empty query because TMDB itself would reject it; this is a fail-fast input guard. Note that q=None is also coerced to empty via (q or '').strip(), so passing None triggers the same error rather than a TypeError.

Source

Thrown at Co-creation-projects/aatanxiao12-beep-YingQian/backend/app/services/movie_service.py:313

        if movie_id <= 0:
            raise MovieServiceError("movie_id 必须为正整数", status_code=400)

        data = self._get(
            f"/movie/{movie_id}",
            {"append_to_response": "credits"},
        )
        return self._map_detail(data)

    def search(
        self,
        q: str,
        year: Optional[int] = None,
        page: int = 1,
    ) -> List[CandidateMovie]:
        """按关键词搜索电影(TMDB GET /search/movie)。"""
        query = (q or "").strip()
        if not query:
            raise MovieServiceError("搜索关键词 q 不能为空", status_code=400)

        data = self._get(
            "/search/movie",
            {
                "query": query,
                "year": year,
                "page": page,
            },
        )
        return [self._map_result(item) for item in data.get("results") or []]

    def discover(
        self,
        with_genres: Optional[str] = None,
        year: Optional[int] = None,
        year_gte: Optional[int] = None,
        year_lte: Optional[int] = None,
        max_runtime: Optional[int] = None,

View on GitHub (pinned to 606a07d341)

Solutions

  1. Validate non-empty q at the API schema level (min_length=1) so FastAPI returns 422 with a field-specific message
  2. Strip input in the caller and skip the search call (or prompt the user) when empty instead of catching the error
  3. For agent tool schemas, mark query as required with a description forbidding empty strings

Example fix

# before
@app.get("/movies/search")
async def search_movies(q: str | None = None):
    return service.search(q)  # raises 400 on empty

# after
from pydantic import field_validator

class SearchQuery(BaseModel):
    q: str
    @field_validator("q")
    @classmethod
    def q_not_blank(cls, v: str) -> str:
        v = v.strip()
        if not v:
            raise ValueError("q 不能为空")
        return v
Defensive patterns

Strategy: validation

Validate before calling

def searchable(q: str | None) -> bool:
    return isinstance(q, str) and q.strip() != ''

Type guard

def is_non_blank_str(v) -> bool:
    return isinstance(v, str) and len(v.strip()) > 0

Prevention

When it happens

Trigger: search('') or search(' '); q=None from an omitted request field; whitespace-only input from a form; a string that became empty after normalization; LLM tool call with query=''.

Common situations: Frontend submitting an untouched search box; agent deciding to search with no keyword; whitespace from copy-paste; API consumers treating q as optional.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/64eb4110ba6f969b. Report an issue: GitHub.