VectifyAI/PageIndex · error · ValueError

offset must be non-negative

Error message

offset must be non-negative

What it means

list_documents requires a non-negative offset; negative offsets are rejected with ValueError before any store access. Offset is a skip count, not an index, so -1 'last item' semantics are unsupported.

Source

Thrown at pageindex/local_api.py:354

            raise PageIndexAPIError("Failed to get document metadata: Document not found")
        return {key: meta.get(key) for key in
                ("id", "name", "description", "status", "createdAt", "pageNum", "folderId")}

    def delete_document(self, doc_id: str) -> dict[str, Any]:
        if not self._store.delete_document(doc_id):
            raise PageIndexAPIError("Failed to delete document: Document not found.")
        return {"message": "Document deleted successfully."}

    def list_documents(
        self,
        limit: int = 50,
        offset: int = 0,
        folder_id: str | None = None,
    ) -> dict[str, Any]:
        if limit < 1 or limit > 100:
            raise ValueError("limit must be between 1 and 100")
        if offset < 0:
            raise ValueError("offset must be non-negative")
        if folder_id is not None:
            raise PageIndexAPIError(
                "Failed to list documents: folders are not supported in local mode."
            )
        metas = sorted(self._store.list_metas(), key=lambda m: m.get("id") or "")
        metas.sort(key=lambda m: m.get("createdAt") or "", reverse=True)
        documents = [{
            "id": m.get("id"),
            "name": m.get("name"),
            "description": m.get("description"),
            "status": m.get("status"),
            "createdAt": m.get("createdAt"),
            "pageNum": m.get("pageNum", 0),
            "folderId": None,
            "metadata": m.get("metadata"),
            "features": {},
        } for m in metas[offset:offset + limit]]
        return {

View on GitHub (pinned to afb5e11976)

Solutions

  1. Clamp offset: offset = max(0, computed_offset)
  2. Fix page-number conversion to (page - 1) * limit with 1-based pages
  3. Guard pagination inputs before calling

Example fix

# before
client.list_documents(offset=page * -10)

# after
client.list_documents(offset=max(0, (page - 1) * 50))
Defensive patterns

Strategy: validation

Validate before calling

offset = max(0, int(offset or 0))
client.list_documents(limit=limit, offset=offset)

Type guard

def is_valid_offset(offset) -> bool:
    return isinstance(offset, int) and not isinstance(offset, bool) and offset >= 0

Try / catch

null

Prevention

When it happens

Trigger: Calling list_documents(offset=-1) or passing an offset computed as start_index - page_size that goes negative on the first page.

Common situations: Off-by-one in cursor math, converting from 1-based page numbers incorrectly (page-1)*size when page=0, mirroring SQL OFFSET tricks.

Related errors


AI-assisted analysis of VectifyAI/PageIndex@afb5e11976 (2026-08-27). Data as JSON: /api/errors/5c5c8b9caf4b8550. Report an issue: GitHub.