Tencent/WeKnora · warning
invalid cursor %q
Error message
invalid cursor %q
What it means
GetIndexView parses the opaque pagination cursor as a non-negative integer offset. If the cursor is non-numeric or negative, the service rejects it with 'invalid cursor %q' instead of guessing a default. This is a strict input-validation guard for paginated wiki index views.
Source
Thrown at internal/application/service/wiki_page.go:488
limit int,
cursor string,
) (*types.WikiIndexResponse, error) {
indexPage, err := s.GetIndex(ctx, kbID)
if err != nil {
return nil, fmt.Errorf("load index page: %w", err)
}
if limit <= 0 {
limit = 50
}
if limit > 200 {
limit = 200
}
offset := 0
if cursor != "" {
v, parseErr := strconv.Atoi(cursor)
if parseErr != nil || v < 0 {
return nil, fmt.Errorf("invalid cursor %q", cursor)
}
offset = v
}
// Default to every known content type when the caller passes no
// filter. Any unknown request-time type is passed through verbatim so
// future page types (declared in types/wiki_page.go) start showing
// up in the index the moment the LLM starts creating them, without a
// handler change.
selected := pageTypes
if len(selected) == 0 {
selected = append([]string{}, wikiIndexContentPageTypes...)
}
groups := make([]types.WikiIndexGroup, 0, len(selected))
for _, pt := range selected {
entries, total, listErr := s.repo.ListByTypeLight(ctx, kbID, pt, limit, offset)
if listErr != nil {View on GitHub (pinned to 988cbb0330)
Solutions
- Pass only the exact cursor string previously returned by the API, or omit it entirely to start from offset 0.
- Strip whitespace and confirm the cursor is a non-negative integer before sending it.
- If migrating from a token-based cursor API, map old tokens to numeric offsets client-side before calling.
- Return a clear 400 to the end user prompting them to restart pagination from the first page.
Example fix
// before GET /api/wiki/index?cursor=abc // after GET /api/wiki/index // or resume with a valid offset GET /api/wiki/index?cursor=200
Defensive patterns
Strategy: validation
Validate before calling
func validCursor(c string) bool {
if c == "" { return true } // empty means start from beginning
v, err := strconv.Atoi(strings.TrimSpace(c))
return err == nil && v >= 0
}
if !validCursor(cursor) { cursor = "" } Try / catch
entries, err := svc.GetIndexView(ctx, kbID, cursor)
if err != nil && strings.Contains(err.Error(), "invalid cursor") {
entries, err = svc.GetIndexView(ctx, kbID, "") // restart pagination
} Prevention
- Always echo back cursors verbatim from prior responses; never construct them manually
- Treat empty cursor as 'first page' rather than sending placeholders
- Normalize/trim user-supplied cursor input before sending
- When migrating APIs, convert old token cursors to numeric offsets client-side
When it happens
Trigger: Calling GetIndexView (or the HTTP endpoint backed by it) with a cursor query parameter that is not a base-10 integer (e.g. cursor=abc, cursor='', base64/glyph cursors from a different API) or a negative number like cursor=-5.
Common situations: Clients sending cursors copied from another paginated API (page tokens vs numeric offsets); frontends echoing back mutated or truncated cursor strings; stale bookmarks with hand-edited URLs; API version mismatches where cursor formats changed.
Related errors
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/b944fee78b1a9356.
Report an issue: GitHub.