zylon-ai/private-gpt · error · ValueError

Offset cannot be negative

Error message

Offset cannot be negative

What it means

ValueError from BraveSearchProvider._validate_query_params when the pagination offset is negative. Brave Search pagination uses offset >= 0; the provider validates this client-side (note that num_links out of range is only clamped with a warning, but a negative offset is a hard error).

Source

Thrown at private_gpt/components/web/web_search/providers/brave.py:96

    async def validate(self) -> None:
        if not self._api_key or not self._api_key.strip():
            raise ValueError("Brave Search API key is not configured")

    def _validate_query_params(
        self, query: str, num_links: int, offset: int
    ) -> tuple[str, int, int]:
        if not query or not query.strip():
            raise ValueError("Search query cannot be empty")

        normalized_num_links = max(1, min(20, num_links))  # Brave allows 1-20
        if normalized_num_links != num_links:
            logger.warning(
                f"Num_links {num_links} outside valid range [1,20], clamped to {normalized_num_links}"
            )

        if offset < 0:
            raise ValueError("Offset cannot be negative")

        return query, normalized_num_links, offset

    async def _execute_http_request(
        self,
        query: str,
        num_links: int,
        offset: int,
        result_filter: str,
        safesearch: bool,
        freshness: str | None,
        spellcheck: bool,
        language: str | None,
    ) -> Any:
        """Execute HTTP request to Brave Search API.

        This method performs the actual HTTP call without retry logic,
        allowing for easier testing and mocking.

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Clamp offset at the call site: offset = max(0, desired_offset).
  2. Fix the pagination arithmetic (use page-1 with pages starting at 1, or multiply 0-based index by page size).
  3. Add a unit test asserting offsets never go negative for the first page.

Example fix

# before
offset = (page - 1) * page_size  # page is 0-based -> -page_size on first call

# after
offset = max(0, page) * page_size  # or page starting at 1
Defensive patterns

Strategy: validation

Validate before calling

def normalize_offset(offset: int) -> int:
    if offset < 0:
        raise ValueError('offset must be >= 0')
    return offset

offset = normalize_offset((page - 1) * page_size if page >= 1 else 0)

Try / catch

try:
    results = await provider.make_query(q, n, offset=offset)
except ValueError as e:
    if str(e) == 'Offset cannot be negative':
        results = await provider.make_query(q, n, offset=0)
    else:
        raise

Prevention

When it happens

Trigger: Passing offset=-1 via make_query kwargs (e.g. search(query, offset=page-1) with page=0); a pagination UI computing offset as (page-1)*n with page starting at 0 instead of 1.

Common situations: Off-by-one bugs in pagination loops; callers mixing 0-based page indices with Brave's page/offset semantics.

Related errors


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