From 77c0a0551fbbba955df202005fcdb1e923924da8 Mon Sep 17 00:00:00 2001 From: rafael kovashikawa Date: Sat, 30 May 2026 23:29:55 +0100 Subject: [PATCH 1/3] fix(proxy): allow /.well-known/* on self-hosted to unblock workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The self-hosted proxy whitelist (active when NEXT_PUBLIC_IS_CAP !== "true") did not include /.well-known/, so the Vercel Workflows runtime — which dispatches itself via HTTP to /.well-known/workflow/v1/{step,flow,webhook} — was 307-redirected to /login on every call. The transcription workflow starts, the workflow runtime enqueues the first step, the HTTP callback is intercepted, and no step ever executes. Symptom on self-host: video uploads succeed, transcription is never performed, AI features never run. Logs show transcribeVideo() being called but no `[transcribe]` step lines and no Deepgram/Whisper request ever fires. Adding /.well-known/ to the same whitelist that already includes /api, /login, etc. restores the workflow callback path. Resolves #1774. Root cause behind self-host AI breakage reported in #1356 and #1550. --- apps/web/proxy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/web/proxy.ts b/apps/web/proxy.ts index da1a3bd261..e5f28c0d14 100644 --- a/apps/web/proxy.ts +++ b/apps/web/proxy.ts @@ -50,7 +50,8 @@ export async function proxy(request: NextRequest) { path.startsWith("/self-hosting") || path.startsWith("/download") || path.startsWith("/terms") || - path.startsWith("/verify-otp") + path.startsWith("/verify-otp") || + path.startsWith("/.well-known/") ) && process.env.NODE_ENV !== "development" ) From 5a3ea5c4b96d3f95c4288bd9407747474689f694 Mon Sep 17 00:00:00 2001 From: rafael kovashikawa Date: Sat, 30 May 2026 23:30:29 +0100 Subject: [PATCH 2/3] fix(proxy): allow /embed/* on self-hosted to unblock iframe embeds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The self-hosted proxy whitelist (active when NEXT_PUBLIC_IS_CAP !== "true") did not include /embed/, so embed routes were 307-redirected to /login. This broke