{"record":{"id":"db047382c5e65d08","repo":"supabase/supabase","slug":"missingenvvars-join-env-variables-are-not","errorCode":null,"errorMessage":"${missingEnvVars.join(', ')} env variables are not set","messagePattern":"(.+?) env variables are not set","errorType":"http","errorClass":null,"httpStatus":500,"severity":"critical","filePath":"apps/studio/pages/api/platform/projects/[ref]/analytics/log-drains/[uuid].ts","lineNumber":16,"sourceCode":"import { NextApiRequest, NextApiResponse } from 'next'\n\nimport { apiWrapper } from '@/lib/api/apiWrapper'\nimport { PROJECT_ANALYTICS_URL } from '@/lib/constants/api'\n\nexport default (req: NextApiRequest, res: NextApiResponse) => apiWrapper(req, res, handler)\n\nasync function handler(req: NextApiRequest, res: NextApiResponse) {\n  const { method } = req\n  const { uuid } = req.query\n\n  const missingEnvVars = envVarsSet()\n\n  if (missingEnvVars !== true) {\n    return res\n      .status(500)\n      .json({ error: { message: `${missingEnvVars.join(', ')} env variables are not set` } })\n  }\n\n  const baseUrl = PROJECT_ANALYTICS_URL\n  if (!baseUrl) {\n    return res.status(500).json({ error: { message: `LOGFLARE_URL env variable is not set` } })\n  }\n\n  switch (method) {\n    case 'GET':\n      // get log drain\n      const url = new URL(baseUrl)\n      url.pathname = `/api/backends/${uuid}`\n      const result = await fetch(url, {\n        method: 'GET',\n        headers: {\n          Authorization: `Bearer ${process.env.LOGFLARE_PRIVATE_ACCESS_TOKEN}`,\n          'Content-Type': 'application/json',","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/supabase/supabase/blob/beee91b9c2228dd57302dec75c733baaa84ab543/apps/studio/pages/api/platform/projects/[ref]/analytics/log-drains/[uuid].ts#L1-L34","documentation":"The log-drain item route checks required env vars before doing any work: if LOGFLARE_PRIVATE_ACCESS_TOKEN or LOGFLARE_URL is unset, envVarsSet() returns the missing names and the handler returns 500 listing them. This is a server configuration defect — the proxy cannot authenticate to LogFlare upstream.","triggerScenarios":"Any GET/PUT/DELETE to /api/platform/projects/{ref}/analytics/log-drains/{uuid} when the Studio server lacks one or both of LOGFLARE_PRIVATE_ACCESS_TOKEN / LOGFLARE_URL in its environment.","commonSituations":"Local Studio run without a .env LOGFLARE_* block; a deployment where secrets were not injected; a CI/test environment that never provisioned LogFlare credentials.","solutions":["Set LOGFLARE_URL and LOGFLARE_PRIVATE_ACCESS_TOKEN in the Studio server environment (.env.local for dev, secrets for deploy).","Restart the Studio process so it picks up the new env vars.","Confirm envVarsSet() returns true before exercising the log-drains UI."],"exampleFix":"// before — .env.local missing entries\n// after\nLOGFLARE_URL=https://logflare.example.com/api/\nLOGFLARE_PRIVATE_ACCESS_TOKEN=your-token-here","handlingStrategy":"validation","validationCode":"// Server boot check\nfunction assertLogflareEnv() {\n  const missing = ['LOGFLARE_PRIVATE_ACCESS_TOKEN', 'LOGFLARE_URL'].filter((k) => !process.env[k])\n  if (missing.length) throw new Error(`Missing LogFlare env: ${missing.join(', ')}`)\n}\nassertLogflareEnv()","typeGuard":"function logflareEnvComplete(): boolean {\n  return Boolean(process.env.LOGFLARE_PRIVATE_ACCESS_TOKEN && process.env.LOGFLARE_URL)\n}","tryCatchPattern":"try {\n  const r = await fetch(`/api/platform/projects/${ref}/analytics/log-drains/${uuid}`, { method: 'GET' })\n  if (r.status === 500) {\n    const body = await r.json().catch(() => ({}))\n    if (/env variables are not set/.test(body?.error?.message ?? '')) {\n      // surface to operator: LogFlare env misconfigured\n    }\n  }\n} catch (err) { /* network */ }","preventionTips":["Add a startup health check that asserts LogFlare env vars are present.","Fail the build/deploy if required secrets are missing rather than 500-ing at request time."],"tags":["env-vars","logflare","log-drains","server-config","http-500"],"backgroundTag":null,"analyzedSha":"beee91b9c2228dd57302dec75c733baaa84ab543","analyzedAt":"2026-08-12T06:51:48.935Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}