{"record":{"id":"f6f195bcf9828878","repo":"hcengineering/platform","slug":"failed-to-fetch-deepgram-requests-res-status","errorCode":null,"errorMessage":"Failed to fetch deepgram requests ${res.status}: ${text}","messagePattern":"Failed to fetch deepgram requests (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/ai-bot/pod-ai-bot/src/billing.ts","lineNumber":85,"sourceCode":"  }\n  if (end != null) {\n    url.searchParams.set('end', end.toISOString())\n  }\n\n  if (page != null) {\n    url.searchParams.set('page', page.toString())\n  }\n\n  url.searchParams.set('limit', '100')\n\n  const res = await fetch(url, {\n    headers: { Authorization: `Token ${config.DeepgramApiKey}` }\n  })\n\n  if (!res.ok) {\n    const text = await res.text()\n    ctx.error('Failed to fetch deepgram requests', { status: res.status, text })\n    throw new Error(`Failed to fetch deepgram requests ${res.status}: ${text}`)\n  }\n\n  return await res.json()\n}\n\nfunction extractExtra (path: string): Record<string, any> {\n  try {\n    const query = path.split('?')[1]\n    if (query == null) return {}\n    const params = new URLSearchParams(query)\n    const extras = params.getAll('extra')\n    return Object.fromEntries(extras.map((pair) => pair.split(':', 2)).filter(([k, v]) => k != null && v != null))\n  } catch {\n    return {}\n  }\n}\n\nfunction extractWorkspace (req: DeepgramRequest): WorkspaceUuid | undefined {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/ai-bot/pod-ai-bot/src/billing.ts#L67-L103","documentation":"fetchDeepgramRequests calls the Deepgram API to fetch usage/request records; when the HTTP response is not ok, it logs the status and body via ctx.error and throws an Error embedding both. This means the Deepgram request itself failed (auth, bad query params, rate limiting, or upstream outage) and no billing data could be retrieved.","triggerScenarios":"Any Deepgram HTTP response with res.ok === false: invalid or missing DEEPGRAM API key (401/403), malformed date-range/project-id query parameters (400), rate limits (429), or Deepgram service errors (5xx).","commonSituations":"Expired or rotated Deepgram API key in config; wrong project id in the request URL; billing job querying a time range before the project existed; Deepgram outage or network proxy returning error pages.","solutions":["Check config.DeepgramApiKey is set and valid (test with a simple Deepgram API call)","Inspect res.status and the body text in the error/log to identify auth vs bad-request vs server error","Verify the request URL, project id and query parameters against current Deepgram API docs","Retry with backoff if status is 429/5xx"],"exampleFix":"// before\nheaders: { Authorization: `Token ${config.DeepgramApiKey}` }\n// after (fail fast with a clear config check)\nif (!config.DeepgramApiKey) throw new Error('DeepgramApiKey is not configured')\nheaders: { Authorization: `Token ${config.DeepgramApiKey}` }","handlingStrategy":"try-catch","validationCode":"if (!config.DeepgramApiKey) {\n  throw new Error('DEEPGRAM API key missing: set config.DeepgramApiKey before fetching usage')\n}","typeGuard":null,"tryCatchPattern":"try {\n  const requests = await billing.fetchDeepgramRequests(params)\n} catch (err) {\n  const msg = err instanceof Error ? err.message : String(err)\n  const status = Number(msg.match(/requests (\\d{3})/)?.[1] ?? 0)\n  if (status === 401 || status === 403) console.error('Check Deepgram API key')\n  else if (status === 429 || status >= 500) scheduleRetryWithBackoff()\n  else console.error('Deepgram request failed:', msg)\n}","preventionTips":["Validate DeepgramApiKey presence at service startup","Log res.status and body on every non-ok response for diagnosis","Add retry with exponential backoff for 429/5xx responses","Pin and monitor Deepgram API version; alert on sustained failures in the billing job"],"tags":["http","network","third-party-api","billing"],"backgroundTag":"upstream-api-request-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}