{"record":{"id":"d89545d83deb7722","repo":"Budibase/budibase","slug":"expected-indexed-request-ids-to-be-an-array","errorCode":null,"errorMessage":"Expected indexed request IDs to be an array","messagePattern":"Expected indexed request IDs to be an array","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/server/src/sdk/workspace/ai/agentLogs/shared.ts","lineNumber":280,"sourceCode":"\nfunction encodeKeyPart(value: string): string {\n  return encodeURIComponent(value)\n}\n\nexport function getSessionDocId(agentId: string, sessionId: string): string {\n  const encodedAgentId = encodeKeyPart(agentId)\n  const encodedSessionId = encodeKeyPart(sessionId)\n  return `${DocumentType.AGENT_LOG_SESSION}${SEPARATOR}${encodedAgentId}${SEPARATOR}${encodedSessionId}`\n}\n\nexport function parseIndexedRequestIds(value?: string): Set<string> {\n  if (!value) {\n    return new Set()\n  }\n\n  const parsed = JSON.parse(value)\n  if (!Array.isArray(parsed)) {\n    throw new Error(\"Expected indexed request IDs to be an array\")\n  }\n  if (parsed.some(item => typeof item !== \"string\")) {\n    throw new Error(\"Expected indexed request IDs to contain only strings\")\n  }\n\n  return new Set(parsed)\n}\n\nexport function getWorkspaceDbForEnvironment(environment: AgentLogEnvironment) {\n  if (environment === \"development\") {\n    return context.getDevWorkspaceDB()\n  }\n  if (environment === \"production\") {\n    return context.getProdWorkspaceDB()\n  }\n\n  throw new HTTPError(\"Invalid environment query\", 400)\n}","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/ai/agentLogs/shared.ts#L262-L298","documentation":"parseIndexedRequestIds parses a stored/serialized string of indexed LiteLLM request IDs. It JSON.parses the value and requires the result to be an array; anything else (object, number, string, etc.) throws a plain Error(\"Expected indexed request IDs to be an array\"). This guards against corrupted or wrongly-shaped persisted data for the agent log session index document.","triggerScenarios":"Reading an AgentLogSessionIndexDoc (or other doc) whose request-IDs field holds JSON that parses to a non-array — e.g. an object {\"id\":...}, a bare number, or a JSON string like \"\\\"abc\\\"\".","commonSituations":"A document was hand-edited or written by an older/newer code version with a different shape; a migration wrote an object instead of an array; a client supplied a non-array value that got persisted verbatim.","solutions":["Inspect the stored document and rewrite the field as a JSON array of string IDs","Fix the writer that persisted the wrong shape so it stores an array","Wrap the parse call in try/catch and fall back to an empty Set or reindex the session"],"exampleFix":"// before\nconst ids = parseIndexedRequestIds(doc.requestIds) // throws on corrupted doc\n// after\nfunction safeParseIndexedRequestIds(value?: string): Set<string> {\n  try {\n    return parseIndexedRequestIds(value)\n  } catch {\n    return new Set()\n  }\n}","handlingStrategy":"type-guard","validationCode":"function isStringArray(value: unknown): value is string[] {\n  return Array.isArray(value) && value.every(item => typeof item === \"string\")\n}","typeGuard":"function isStringArray(value: unknown): value is string[] {\n  return Array.isArray(value) && value.every(item => typeof item === \"string\")\n}\n\nfunction safeParse(value?: string): Set<string> {\n  if (!value) return new Set()\n  const parsed: unknown = JSON.parse(value)\n  return isStringArray(parsed) ? new Set(parsed) : new Set()\n}","tryCatchPattern":"try {\n  const ids = parseIndexedRequestIds(value)\n} catch (err) {\n  console.warn(\"Corrupt indexed request IDs, treating as empty\", err)\n  const ids = new Set<string>()\n}","preventionTips":["Always serialize request IDs as JSON.stringify of a string[]","Add a migration check that rewrites non-array or non-string index fields","Read the field defensively and fall back to an empty Set"],"tags":["json-parsing","data-corruption","schema-validation","agent-logs"],"backgroundTag":"unexpected-json-shape","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}