diff --git a/apps/docs/content/guides/functions/auth.mdx b/apps/docs/content/guides/functions/auth.mdx index 071707aeaf1..b052c70362e 100644 --- a/apps/docs/content/guides/functions/auth.mdx +++ b/apps/docs/content/guides/functions/auth.mdx @@ -93,14 +93,27 @@ import Stripe from 'npm:stripe' const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!) +// Deno has no synchronous Node crypto, so signature verification must go through +// Stripe's SubtleCryptoProvider. The synchronous `constructEvent()` throws +// "SubtleCryptoProvider cannot be used in a synchronous context" on this runtime. +const cryptoProvider = Stripe.createSubtleCryptoProvider() + export default { fetch: withSupabase({ auth: 'none' }, async (req, ctx) => { const signature = req.headers.get('stripe-signature') ?? '' const body = await req.text() try { - stripe.webhooks.constructEvent(body, signature, Deno.env.get('STRIPE_WEBHOOK_SECRET')!) - } catch { + await stripe.webhooks.constructEventAsync( + body, + signature, + Deno.env.get('STRIPE_WEBHOOK_SECRET')!, + undefined, + cryptoProvider + ) + } catch (err) { + // Log the reason so a configuration error isn't mistaken for a forged payload. + console.error('Stripe signature verification failed:', err) return new Response('bad signature', { status: 400 }) } diff --git a/apps/docs/content/guides/functions/compression.mdx b/apps/docs/content/guides/functions/compression.mdx index c735106fb99..eb385e08b79 100644 --- a/apps/docs/content/guides/functions/compression.mdx +++ b/apps/docs/content/guides/functions/compression.mdx @@ -45,6 +45,6 @@ Deno.serve(async (req) => { -Edge functions have a runtime memory limit of 150MB. Overly large compressed payloads may result in an out-of-memory error. +Edge functions have a runtime memory limit of 256MB. Overly large compressed payloads may result in an out-of-memory error. diff --git a/apps/docs/content/guides/functions/cors.mdx b/apps/docs/content/guides/functions/cors.mdx index 351beb10421..6ae913d9cc9 100644 --- a/apps/docs/content/guides/functions/cors.mdx +++ b/apps/docs/content/guides/functions/cors.mdx @@ -49,7 +49,8 @@ export default { const { name } = await req.json() return Response.json({ message: `Hello ${name}!` }, { headers: corsHeaders }) } catch (error) { - return Response.json({ error: error.message }, { status: 400, headers: corsHeaders }) + const message = error instanceof Error ? error.message : String(error) + return Response.json({ error: message }, { status: 400, headers: corsHeaders }) } }, } @@ -83,6 +84,7 @@ export const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type, x-retry-count, traceparent, tracestate, baggage', + 'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS', } ``` diff --git a/apps/docs/content/guides/functions/dependencies.mdx b/apps/docs/content/guides/functions/dependencies.mdx index 5278bdeea53..69127466998 100644 --- a/apps/docs/content/guides/functions/dependencies.mdx +++ b/apps/docs/content/guides/functions/dependencies.mdx @@ -103,7 +103,7 @@ You can override the default import map location using the `--import-map { }) } catch (error) { console.error('Function error:', error) - return new Response(JSON.stringify({ error: error.message }), { + return new Response(JSON.stringify({ error: 'Internal Server Error' }), { headers: { 'Content-Type': 'application/json' }, status: 500, }) @@ -47,7 +47,7 @@ Within your client-side code, an Edge Function can throw three types of errors: - **`FunctionsFetchError`**: Function couldn't be reached at all ```jsx -import { FunctionsHttpError, FunctionsRelayError, FunctionsFetchError } from '@supabase/supabase-js' +import { FunctionsFetchError, FunctionsHttpError, FunctionsRelayError } from '@supabase/supabase-js' const { data, error } = await supabase.functions.invoke('hello', { headers: { 'my-custom-header': 'my-custom-header-value' }, diff --git a/apps/docs/content/guides/functions/examples/mcp-server-mcp-lite.mdx b/apps/docs/content/guides/functions/examples/mcp-server-mcp-lite.mdx index 9b6cebcbe2e..f0df57dcff8 100644 --- a/apps/docs/content/guides/functions/examples/mcp-server-mcp-lite.mdx +++ b/apps/docs/content/guides/functions/examples/mcp-server-mcp-lite.mdx @@ -16,7 +16,7 @@ This guide shows you how to scaffold, develop, and deploy an MCP server using mc This combination offers several advantages: -- **Zero cold starts**: Edge Functions stay warm for fast responses +- **Fast cold starts**: Edge Functions boot in milliseconds, and warm isolates serve subsequent requests without restarting - **Global distribution**: Deploy once and run everywhere - **Direct database access**: Connect directly to your Supabase Postgres - **Minimal footprint**: mcp-lite has zero runtime dependencies diff --git a/apps/docs/content/guides/functions/function-configuration.mdx b/apps/docs/content/guides/functions/function-configuration.mdx index 86bbfc2649e..59b4fd82c8e 100644 --- a/apps/docs/content/guides/functions/function-configuration.mdx +++ b/apps/docs/content/guides/functions/function-configuration.mdx @@ -28,7 +28,7 @@ import_map = './functions/image-processor/import_map.json' # Custom entrypoint for legacy function using JavaScript [functions.legacy-processor] -entrypoint = './functions/legacy-processor/index.js +entrypoint = './functions/legacy-processor/index.js' ``` This configuration tell Supabase that the `stripe-webhook` function doesn't require a valid JWT, the `image-processor` function uses a custom import map, and `legacy-processor` uses a custom entrypoint. @@ -80,7 +80,7 @@ Save your Function as a JavaScript file (e.g. `index.js`) update the `supabase/c ```toml [functions.hello-world] -entrypoint = './index.js' # path must be relative to config.toml +entrypoint = './functions/hello-world/index.js' # path must be relative to config.toml ``` You can use any `.ts`, `.js`, `.tsx`, `.jsx` or `.mjs` file as the entrypoint for a Function. diff --git a/apps/docs/content/troubleshooting/edge-function-cpu-limits.mdx b/apps/docs/content/troubleshooting/edge-function-cpu-limits.mdx index 3ff348531e2..4de75b8ed42 100644 --- a/apps/docs/content/troubleshooting/edge-function-cpu-limits.mdx +++ b/apps/docs/content/troubleshooting/edge-function-cpu-limits.mdx @@ -9,7 +9,7 @@ Learn how Edge Functions manage CPU resources and what happens when limits are r ## How isolates work -An isolate is like a worker that can handle multiple requests for a function. It works until a time limit of 400 seconds is reached. Edge Functions use isolates with soft and hard CPU limits. +An isolate is like a worker that can handle multiple requests for a function. It works until it reaches the wall clock time limit. Edge Functions use isolates with soft and hard CPU limits. ## Soft limit @@ -17,7 +17,7 @@ When the isolate hits the soft limit, it **retires**. This means: - It won't take on any new requests - It will finish processing requests it's already working on -- It keeps going until it hits the hard limit for CPU time or reaches the 400-second time limit, whichever comes first +- It keeps going until it hits the hard limit for CPU time or reaches the wall clock time limit, whichever comes first ## Hard limit @@ -29,8 +29,8 @@ If there are new requests after the soft limit is reached: ## Current limits -- **Wall clock time limit:** 400 seconds total duration -- **CPU execution time:** 200 milliseconds of active computing +- **Wall clock time limit:** 150 seconds on the Free plan, 400 seconds on paid plans +- **CPU execution time:** 2 seconds of active computing per request ## What happens when limits are exceeded diff --git a/apps/docs/content/troubleshooting/edge-function-monitoring-resource-usage.mdx b/apps/docs/content/troubleshooting/edge-function-monitoring-resource-usage.mdx index 38a8b415c05..56eec361672 100644 --- a/apps/docs/content/troubleshooting/edge-function-monitoring-resource-usage.mdx +++ b/apps/docs/content/troubleshooting/edge-function-monitoring-resource-usage.mdx @@ -47,7 +47,7 @@ Edge Functions have limited resources compared to traditional servers. Optimize - **Memory efficiency:** Avoid loading large datasets into memory - **CPU optimization:** Minimize complex computations -- **Execution time:** Keep functions under 60 seconds +- **Execution time:** Send a response before the 150-second request idle timeout ## Best practices diff --git a/apps/docs/content/troubleshooting/edge-function-shutdown-reasons-explained.mdx b/apps/docs/content/troubleshooting/edge-function-shutdown-reasons-explained.mdx index eca96448772..2614ec2d724 100644 --- a/apps/docs/content/troubleshooting/edge-function-shutdown-reasons-explained.mdx +++ b/apps/docs/content/troubleshooting/edge-function-shutdown-reasons-explained.mdx @@ -135,7 +135,7 @@ Make your functions safe to run multiple times with the same input. Use executio ```typescript // Store execution_id to detect retries -const executionId = Deno.env.get('EXECUTION_ID') +const executionId = Deno.env.get('SB_EXECUTION_ID') const alreadyProcessed = await checkIfProcessed(executionId) if (alreadyProcessed) { diff --git a/apps/docs/content/troubleshooting/edge-function-takes-too-long-to-respond.mdx b/apps/docs/content/troubleshooting/edge-function-takes-too-long-to-respond.mdx index e47714f1608..99ce65bbf1d 100644 --- a/apps/docs/content/troubleshooting/edge-function-takes-too-long-to-respond.mdx +++ b/apps/docs/content/troubleshooting/edge-function-takes-too-long-to-respond.mdx @@ -5,7 +5,7 @@ keywords = [ "slow", "timeout", "performance", "boot", "response time", "edge fu database_id = "89b868a9-17fe-4c6d-86f6-0b04e5794678" --- -Edge Functions have a 60-second execution limit. If your function is taking too long to respond, follow these steps to diagnose and optimize performance. +Edge Functions must send a response within the 150-second request idle timeout, or the platform returns a 504 Gateway Timeout. If your function is taking too long to respond, follow these steps to diagnose and optimize performance. ## Diagnose the issue diff --git a/apps/docs/content/troubleshooting/edge-function-wall-clock-time-limit-reached-Nk38bW.mdx b/apps/docs/content/troubleshooting/edge-function-wall-clock-time-limit-reached-Nk38bW.mdx index 402453a70fc..b7a402227c5 100644 --- a/apps/docs/content/troubleshooting/edge-function-wall-clock-time-limit-reached-Nk38bW.mdx +++ b/apps/docs/content/troubleshooting/edge-function-wall-clock-time-limit-reached-Nk38bW.mdx @@ -19,8 +19,8 @@ When this message appears in the context of your edge function, it means that th **Current Limits Explained** -- Wall Clock Time Limit: Currently set at 400 seconds for the total duration your edge function can run. -- CPU Execution Time: Limited to 200 milliseconds of active computing. +- Wall Clock Time Limit: 150 seconds on the Free plan and 400 seconds on paid plans, for the total duration your edge function can run. +- CPU Execution Time: Limited to 2 seconds of active computing per request. This means that if your edge function completes its task within these time constraints, there's no need to be concerned about the "wall clock time limit reached" error message. diff --git a/apps/docs/content/troubleshooting/unable-to-deploy-edge-function.mdx b/apps/docs/content/troubleshooting/unable-to-deploy-edge-function.mdx index 6c644de9e3e..2ce50a47795 100644 --- a/apps/docs/content/troubleshooting/unable-to-deploy-edge-function.mdx +++ b/apps/docs/content/troubleshooting/unable-to-deploy-edge-function.mdx @@ -28,7 +28,7 @@ supabase functions deploy your-function --debug - **Syntax errors:** TypeScript or JavaScript syntax issues in your function code - **Invalid imports:** Importing modules that don't exist or aren't compatible with Deno -- **Large bundle size:** Functions have a 10MB source code limit. See [Bundle size issues](./edge-function-bundle-size-issues) for more details +- **Large bundle size:** Functions have a maximum size of 20MB when bundled locally through the CLI, or 5MB when bundled server-side, for example through the Management API or Dashboard. See [Bundle size issues](./edge-function-bundle-size-issues) for more details - **Network issues:** Problems reaching the Supabase API during deployment ## Before opening a support ticket @@ -37,9 +37,10 @@ Make sure you're using the latest version of the Supabase CLI: ```bash supabase --version -supabase update ``` +If it's out of date, upgrade using whichever package manager installed the CLI, for example `brew upgrade supabase`, `npm update supabase --save-dev`, or `scoop update supabase`. + If these steps don't resolve the issue, open a support ticket via the Supabase Dashboard and include all output from the diagnostic commands. ## Additional resources