Description
The proxy whitelist in apps/web/proxy.ts redirects all unwhitelisted paths to /login on self-hosted deployments (when NEXT_PUBLIC_IS_CAP !== "true"). The .well-known/workflow/v1/* routes — used by @workflow/world-local for queue dispatch and step execution — aren't in the whitelist.
When start(transcribeVideoWorkflow, ...) (or any other workflow start() call) tries to POST to /.well-known/workflow/v1/flow, it gets a 307 → /login instead of the expected workflow response. The dispatch fails silently, the workflow never executes, and any feature relying on workflows (transcription, AI summaries) stalls.
Reproduction
- Self-host Cap with
NEXT_PUBLIC_IS_CAP unset
- From inside the cap-web container:
wget -qO- http://127.0.0.1:3000/.well-known/workflow/v1/step
Returns the login page HTML instead of a workflow response.
3. Or trigger a transcription: it stalls at transcriptionStatus = "PROCESSING" indefinitely, no /audio/extract calls reach the media-server.
Root cause
In apps/web/proxy.ts lines ~40-56:
if (buildEnv.NEXT_PUBLIC_IS_CAP !== "true") {
if (
!(
path.startsWith("/s/") ||
path.startsWith("/middleware") ||
path.startsWith("/dashboard") ||
path.startsWith("/onboarding") ||
path.startsWith("/api") ||
path.startsWith("/login") ||
path.startsWith("/signup") ||
path.startsWith("/invite") ||
path.startsWith("/self-hosting") ||
path.startsWith("/terms") ||
path.startsWith("/verify-otp")
// /.well-known/ missing — blocks workflow internal routes
// /embed/ also missing — see #906 / PR #1415
) &&
process.env.NODE_ENV !== "development"
)
return NextResponse.redirect(new URL("/login", url.origin));
Fix
Same shape as #906:
path.startsWith("/verify-otp") ||
+ path.startsWith("/embed/") ||
+ path.startsWith("/.well-known/")
The /.well-known/ path is reserved by RFC 8615 for well-known URIs and is a sensible whitelist entry generally — workflow routes, ATproto verification, etc. all live under it.
Verified
After applying both whitelist additions plus the workflow-race fix from #1550, the full transcription + AI pipeline runs end-to-end on self-hosted (Hetzner CPX41, cap-web built from current main).
Environment
- Cap version: built from
main commit 52b0acc
- Self-hosted via Docker compose (Hetzner)
- Other services in stack: Hetzner S3, MySQL 8, cap-media-server (latest)
Description
The proxy whitelist in
apps/web/proxy.tsredirects all unwhitelisted paths to/loginon self-hosted deployments (whenNEXT_PUBLIC_IS_CAP !== "true"). The.well-known/workflow/v1/*routes — used by@workflow/world-localfor queue dispatch and step execution — aren't in the whitelist.When
start(transcribeVideoWorkflow, ...)(or any other workflowstart()call) tries to POST to/.well-known/workflow/v1/flow, it gets a307 → /logininstead of the expected workflow response. The dispatch fails silently, the workflow never executes, and any feature relying on workflows (transcription, AI summaries) stalls.Reproduction
NEXT_PUBLIC_IS_CAPunsetReturns the login page HTML instead of a workflow response.
3. Or trigger a transcription: it stalls at
transcriptionStatus = "PROCESSING"indefinitely, no/audio/extractcalls reach the media-server.Root cause
In
apps/web/proxy.tslines ~40-56:Fix
Same shape as #906:
path.startsWith("/verify-otp") || + path.startsWith("/embed/") || + path.startsWith("/.well-known/")The
/.well-known/path is reserved by RFC 8615 for well-known URIs and is a sensible whitelist entry generally — workflow routes, ATproto verification, etc. all live under it.Verified
After applying both whitelist additions plus the workflow-race fix from #1550, the full transcription + AI pipeline runs end-to-end on self-hosted (Hetzner CPX41,
cap-webbuilt from currentmain).Environment
maincommit 52b0acc