supabase/supabase · critical

${missingEnvVars.join(', ')} env variables are not set

Error message

${missingEnvVars.join(', ')} env variables are not set

What it means

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.

Source

Thrown at apps/studio/pages/api/platform/projects/[ref]/analytics/log-drains/[uuid].ts:16

import { NextApiRequest, NextApiResponse } from 'next'

import { apiWrapper } from '@/lib/api/apiWrapper'
import { PROJECT_ANALYTICS_URL } from '@/lib/constants/api'

export default (req: NextApiRequest, res: NextApiResponse) => apiWrapper(req, res, handler)

async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { method } = req
  const { uuid } = req.query

  const missingEnvVars = envVarsSet()

  if (missingEnvVars !== true) {
    return res
      .status(500)
      .json({ error: { message: `${missingEnvVars.join(', ')} env variables are not set` } })
  }

  const baseUrl = PROJECT_ANALYTICS_URL
  if (!baseUrl) {
    return res.status(500).json({ error: { message: `LOGFLARE_URL env variable is not set` } })
  }

  switch (method) {
    case 'GET':
      // get log drain
      const url = new URL(baseUrl)
      url.pathname = `/api/backends/${uuid}`
      const result = await fetch(url, {
        method: 'GET',
        headers: {
          Authorization: `Bearer ${process.env.LOGFLARE_PRIVATE_ACCESS_TOKEN}`,
          'Content-Type': 'application/json',

View on GitHub (pinned to beee91b9c2)

Solutions

  1. Set LOGFLARE_URL and LOGFLARE_PRIVATE_ACCESS_TOKEN in the Studio server environment (.env.local for dev, secrets for deploy).
  2. Restart the Studio process so it picks up the new env vars.
  3. Confirm envVarsSet() returns true before exercising the log-drains UI.

Example fix

// before — .env.local missing entries
// after
LOGFLARE_URL=https://logflare.example.com/api/
LOGFLARE_PRIVATE_ACCESS_TOKEN=your-token-here
Defensive patterns

Strategy: validation

Validate before calling

// Server boot check
function assertLogflareEnv() {
  const missing = ['LOGFLARE_PRIVATE_ACCESS_TOKEN', 'LOGFLARE_URL'].filter((k) => !process.env[k])
  if (missing.length) throw new Error(`Missing LogFlare env: ${missing.join(', ')}`)
}
assertLogflareEnv()

Type guard

function logflareEnvComplete(): boolean {
  return Boolean(process.env.LOGFLARE_PRIVATE_ACCESS_TOKEN && process.env.LOGFLARE_URL)
}

Try / catch

try {
  const r = await fetch(`/api/platform/projects/${ref}/analytics/log-drains/${uuid}`, { method: 'GET' })
  if (r.status === 500) {
    const body = await r.json().catch(() => ({}))
    if (/env variables are not set/.test(body?.error?.message ?? '')) {
      // surface to operator: LogFlare env misconfigured
    }
  }
} catch (err) { /* network */ }

Prevention

When it happens

Trigger: 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.

Common situations: Local Studio run without a .env LOGFLARE_* block; a deployment where secrets were not injected; a CI/test environment that never provisioned LogFlare credentials.

Related errors


AI-assisted analysis of supabase/supabase@beee91b9c2 (2026-08-12). Data as JSON: /api/errors/db047382c5e65d08. Report an issue: GitHub.