supabase/supabase · error · Error

Failed to test edge function

Error message

Failed to test edge function

What it means

Fallback thrown by testEdgeFunction when the test endpoint returns non-2xx and the body either fails to parse as JSON (caught silently, `data` stays undefined) or lacks `error.message`. The thrown Error carries `cause: { status: data.status }` so callers can read the upstream HTTP status even though the message is generic.

Source

Thrown at apps/studio/data/edge-functions/edge-function-test-mutation.ts:37

}

export async function testEdgeFunction({ url, method, body, headers }: EdgeFunctionTestVariables) {
  const defaultHeaders = await constructHeaders()

  const response = await fetchHandler(`${BASE_PATH}/api/edge-functions/test`, {
    method: 'POST',
    headers: { ...defaultHeaders, 'Content-Type': 'application/json' },
    body: JSON.stringify({ url, method, body, headers }),
  })

  let data: any

  try {
    data = await response.json()
  } catch {}

  if (!response.ok) {
    throw new Error(data.error?.message || 'Failed to test edge function', {
      cause: { status: data.status },
    })
  }

  return data as ResponseData
}

type EdgeFunctionTestData = Awaited<ReturnType<typeof testEdgeFunction>>

export const useEdgeFunctionTestMutation = ({
  onSuccess,
  onError,
  ...options
}: Omit<
  UseCustomMutationOptions<EdgeFunctionTestData, ResponseError, EdgeFunctionTestVariables>,
  'mutationFn'
> = {}) => {
  return useMutation<EdgeFunctionTestData, ResponseError, EdgeFunctionTestVariables>({

View on GitHub (pinned to beee91b9c2)

Solutions

  1. Inspect `error.cause.status` in the catch — it carries the upstream status code.
  2. Open the Network tab and read the raw response body for the true error text.
  3. Confirm the function is deployed and the URL/method in the test panel match the function signature.
  4. Check that authentication headers / API gateway JWT are attached if the function requires them.

Example fix

// before
try { await testEdgeFunction(vars) } catch (e) { toast.error(String(e)) }
// after — surface the upstream status
try { await testEdgeFunction(vars) }
catch (e) {
  const status = (e as Error & { cause?: { status?: number } }).cause?.status
  toast.error(status ? `Edge function test failed (HTTP ${status})` : 'Edge function test failed')
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate request shape before calling the proxy
function validateTestInput({ url, method }: { url: string; method: string }) {
  try { new URL(url) } catch { throw new Error('Provide a valid absolute URL for the function') }
  if (!['GET','POST','PUT','PATCH','DELETE','HEAD','OPTIONS'].includes(method.toUpperCase())) throw new Error('Unsupported HTTP method')
}

Type guard

function hasEdgeError(x: unknown): x is { error: { message: string }; status?: number } {
  return typeof x === 'object' && x !== null && typeof (x as any).error?.message === 'string'
}

Try / catch

try { await testEdgeFunction(vars) }
catch (e) {
  const status = (e as Error & { cause?: { status?: number } }).cause?.status
  toast.error(status ? `Edge function test failed (HTTP ${status})` : 'Edge function test failed')
}

Prevention

When it happens

Trigger: POSTing to the edge-function test proxy returns non-ok. If the body parsed, `data.error?.message` is shown; otherwise the generic 'Failed to test edge function' fires. Empty/non-JSON bodies land here.

Common situations: Edge function URL/method/headers invalid; function returns 5xx and the proxy surfaces no structured error; CORS or auth cookie missing; the function timed out and the gateway returned an HTML error page.

Related errors


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