{"record":{"id":"8d9d89806f72cd17","repo":"Budibase/budibase","slug":"startdate-query-must-be-before-enddate-query","errorCode":null,"errorMessage":"startDate query must be before endDate query","messagePattern":"startDate query must be before endDate query","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/ai/agentLogs.ts","lineNumber":116,"sourceCode":"}\n\nexport async function fetchAgentLogs(\n  ctx: UserCtx<void, FetchAgentLogsResponse>\n) {\n  const { agentId } = ctx.params\n  const { startDate, endDate, bookmark, limit, statusFilter, triggerFilter } =\n    ctx.query as Record<string, string>\n  const defaults = getDefaultLogRange()\n  const sanitizedStartDate =\n    sanitizeDateQuery(startDate, \"startDate\") || defaults.startDate\n  const sanitizedEndDate =\n    sanitizeDateQuery(endDate, \"endDate\") || defaults.endDate\n\n  if (\n    getComparableDate(sanitizedStartDate, \"start\") >\n    getComparableDate(sanitizedEndDate, \"end\")\n  ) {\n    throw new HTTPError(\"startDate query must be before endDate query\", 400)\n  }\n  ctx.body = await sdk.ai.agentLogs.fetchSessions(\n    agentId,\n    sanitizedStartDate,\n    sanitizedEndDate,\n    sanitizeBookmarkQuery(bookmark),\n    sanitizeLimitQuery(limit),\n    statusFilter,\n    triggerFilter\n  )\n}\n\nexport async function fetchAgentLogSession(\n  ctx: UserCtx<void, AgentLogSession | null>\n) {\n  const { agentId } = ctx.params\n  const { sessionId, environment } = ctx.query as Record<string, string>\n  ctx.body = await sdk.ai.agentLogs.fetchSessionDetail(","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/ai/agentLogs.ts#L98-L134","documentation":"This error is thrown when sanitizing the startDate/endDate query parameters for fetching agent log sessions: after both dates are validated, their comparable values are compared and if the start date is chronologically after the end date the request is rejected with 400. The library enforces a forward-looking date range.","triggerScenarios":"Calling fetchAgentLogs with ?startDate=2026-05-01&endDate=2026-04-01 (reversed range), or with time-of-day values that invert the range (startDate=2026-04-02T10:00 vs endDate=2026-04-02T09:00). Date-only values are expanded to start-of-day/end-of-day before comparison.","commonSituations":"UI date-range pickers that allow inverted selections; timezone mixups where one date is UTC and the other local; programmatic callers computing startDate = endDate - duration with sign errors; millisecond vs ISO string inconsistencies.","solutions":["Swap the values so startDate is earlier than or equal to endDate","Verify the caller's date computation (e.g. duration subtraction) is not inverted","Ensure both dates use consistent timezone/format (ISO 8601)","Validate the range in the UI before issuing the request"],"exampleFix":"// before\n?startDate=2026-05-01&endDate=2026-04-01\n// after\n?startDate=2026-04-01&endDate=2026-05-01","handlingStrategy":"validation","validationCode":"function validateDateRange(startDate, endDate) {\n  if (new Date(startDate).getTime() > new Date(endDate).getTime()) {\n    throw new Error(\"startDate must be before or equal to endDate\")\n  }\n  return { startDate, endDate }\n}\nvalidateDateRange(params.startDate, params.endDate)","typeGuard":null,"tryCatchPattern":"try {\n  const sessions = await fetchAgentLogs(agentId, { startDate, endDate })\n} catch (err) {\n  if (err.status === 400 && /startDate query/.test(err.message)) {\n    [startDate, endDate] = [endDate, startDate]\n    return fetchAgentLogs(agentId, { startDate, endDate })\n  }\n  throw err\n}","preventionTips":["Use a date-range picker component that enforces start <= end","Normalize all dates to ISO 8601 UTC before sending","Unit-test any computed date ranges (e.g. last N days) for inversion","Validate ranges client-side before issuing the request"],"tags":["validation","http-400","query-params","date-range"],"backgroundTag":"invalid-date-range","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}