Budibase/budibase · warning · HTTPError

Invalid bookmark query

Error message

Invalid bookmark query

What it means

sanitizeBookmarkQuery validates the pagination bookmark query parameter and throws HTTPError 400 when it is not a pure numeric string. Bookmarks for agent logs are integer-based cursors, so any non-numeric value is rejected before querying.

Source

Thrown at packages/server/src/api/controllers/ai/agentLogs.ts:30

function getDefaultLogRange() {
  const now = new Date()
  const sevenDaysAgo = new Date(now.getTime() - Duration.fromDays(7).toMs())

  return {
    startDate: sevenDaysAgo.toISOString(),
    endDate: now.toISOString(),
  }
}

function sanitizeBookmarkQuery(bookmark?: string): string | undefined {
  const normalizedBookmark = bookmark?.trim()
  if (!normalizedBookmark) {
    return undefined
  }

  if (!/^\d+$/.test(normalizedBookmark)) {
    throw new HTTPError("Invalid bookmark query", 400)
  }

  const parsedBookmark = Number.parseInt(normalizedBookmark, 10)
  if (!Number.isFinite(parsedBookmark) || parsedBookmark < 1) {
    throw new HTTPError("Invalid bookmark query", 400)
  }

  return String(parsedBookmark)
}

function sanitizeLimitQuery(limit?: string): number | undefined {
  const normalizedLimit = limit?.trim()
  if (!normalizedLimit) {
    return undefined
  }

  if (!/^\d+$/.test(normalizedLimit)) {
    throw new HTTPError("Invalid limit query", 400)

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Send only digits as the bookmark value
  2. Use the bookmark value returned by the previous agent-logs response verbatim
  3. Remove the bookmark param to fetch the first page

Example fix

// before
fetch("/api/ai/agent/logs?bookmark=page-2")
// after
fetch("/api/ai/agent/logs?bookmark=20")
Defensive patterns

Strategy: validation

Validate before calling

const bookmark = rawBookmark?.trim(); if (bookmark && !/^\d+$/.test(bookmark)) throw new Error("bookmark must be numeric")

Type guard

const isValidBookmark = (v: unknown): v is string => typeof v === "string" && /^\d+$/.test(v.trim())

Try / catch

try { await api.fetchAgentLogs({ bookmark }) } catch (e) { if (e.status === 400 && e.message === "Invalid bookmark query") { /* reset to first page */ } else throw e }

Prevention

When it happens

Trigger: GET agent logs with ?bookmark=abc, ?bookmark=12ab, or whitespace-only/string values failing the /^\d+$/ test.

Common situations: Client passing an opaque/offset cursor from another API; hand-crafted URL with malformed bookmark; passing undefined-turned-empty handled (returns undefined) but non-numeric strings rejected.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/aaec56857ad6a6b4. Report an issue: GitHub.