{"record":{"id":"bf31142364202f09","repo":"Budibase/budibase","slug":"invalid-litellm-date-value","errorCode":null,"errorMessage":"Invalid LiteLLM date: ${value}","messagePattern":"Invalid LiteLLM date: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/server/src/sdk/workspace/ai/agentLogs/liteLLM.ts","lineNumber":32,"sourceCode":"\nfunction formatLiteLLMDateTime(date: Date): string {\n  const pad = (part: number) => String(part).padStart(2, \"0\")\n  return (\n    [\n      date.getUTCFullYear(),\n      pad(date.getUTCMonth() + 1),\n      pad(date.getUTCDate()),\n    ].join(\"-\") +\n    ` ${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(\n      date.getUTCSeconds()\n    )}`\n  )\n}\n\nfunction getLiteLLMDayBoundary(value: string, mode: \"start\" | \"end\"): string {\n  const parsedDate = parseDate(value)\n  if (!parsedDate) {\n    throw new Error(`Invalid LiteLLM date: ${value}`)\n  }\n\n  const boundary = new Date(parsedDate)\n  if (mode === \"start\") {\n    boundary.setUTCHours(0, 0, 0, 0)\n  } else {\n    boundary.setUTCHours(23, 59, 59, 999)\n  }\n\n  return formatLiteLLMDateTime(boundary)\n}\n\nexport async function fetchLiteLLMRequestSummaryById(\n  requestId: string,\n  startDate?: string,\n  endDate?: string\n): Promise<LiteLLMRequestDetail | null> {\n  const params = new URLSearchParams({","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/ai/agentLogs/liteLLM.ts#L14-L50","documentation":"getLiteLLMDayBoundary converts a user-supplied date string into a UTC day boundary (start 00:00:00.000 or end 23:59:59.999) for LiteLLM log queries. parseDate must produce a valid date; otherwise the input is rejected with 'Invalid LiteLLM date: <value>'.","triggerScenarios":"Calling the LiteLLM log listing endpoints (via getLiteLLMDayBoundary through params) with a startDate/endDate query value that parseDate cannot parse - empty strings, arbitrary text, or unsupported formats.","commonSituations":"Builder UI or API clients sending malformed date query params (e.g. 'yesterday', '2026-13-45', or an empty value); timezone-format mismatches between client and server expectations.","solutions":["Send dates in an ISO 8601 format the parser supports, e.g. 2026-08-28 or 2026-08-28T10:00:00Z.","Validate/parse dates on the client before issuing the request.","Inspect the error message - it echoes the exact invalid value received; fix that param.","Check for empty/null params being stringified into the query string and omit them instead."],"exampleFix":"// before\nGET /ai/agentlogs?startDate=last-week\n// after\nGET /ai/agentlogs?startDate=2026-08-21","handlingStrategy":"validation","validationCode":"const parsed = parseDate(rawDate)\nif (!parsed || Number.isNaN(new Date(parsed).getTime())) {\n  throw new Error(`startDate/endDate must be an ISO date, got: ${rawDate}`)\n}","typeGuard":"const isParsableDate = (v: unknown): v is string => typeof v === \"string\" && parseDate(v) !== null","tryCatchPattern":"try {\n  logs = await listLiteLLMLogs({ startDate, endDate })\n} catch (e) {\n  if (e.message.startsWith(\"Invalid LiteLLM date\")) {\n    return respond400(\"startDate/endDate must be ISO 8601 dates\")\n  }\n  throw e\n}","preventionTips":["Always send ISO 8601 dates (2026-08-28 or with time/Z)","Validate query params before calling the API","Omit date params rather than sending empty strings","Fix the echoed value in the error message - it names the exact bad input"],"tags":["validation","dates","http"],"backgroundTag":"invalid-date-parameter","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}