Summary
On the self-hosted Docker image (ghcr.io/capsoftware/cap-web:latest), every recording gets stuck on "Processing failed". Uploads succeed (segments + manifest.json land in the bucket), but the recording never finishes processing.
Root cause: the Workflow DevKit control-plane routes under /.well-known/workflow/v1/* are not served by their route handlers — they return the Next.js app/SPA HTML shell with HTTP 200. Because the workflow engine advances every durable step by making an HTTP self-call to /.well-known/workflow/v1/flow (and /step), and that call gets a 200 text/html page back instead of the handler, the workflow silently never advances. No error is logged; the run stays pending forever.
This appears to be a Next.js 16 + Turbopack standalone build issue: apps/web/package.json builds with next build --turbopack, and the entire .well-known namespace is unreachable at runtime in the standalone server.
Environment
- Image:
ghcr.io/capsoftware/cap-web:latest (built 2026-06-13, Next 16.2.1, workflow@4.2.0-beta.73, @workflow/world-local@4.1.0-beta.46)
- Self-hosted via the repo
docker-compose.yml (MySQL + MinIO + media-server + cap-web)
- Recording mode:
desktopSegments (in-browser recorder)
Reproduction
- Self-host with the provided docker-compose.
- Record anything via the web recorder.
- Segments +
manifest.json (is_complete: true) upload to the bucket; the media-server is never called; the cap is shown as "Processing failed".
- Inside the container,
.workflow-data/runs/*.json shows the run stuck at "status": "pending" (only a run_created event), and video_uploads.phase stays processing with processing_error = NULL.
Evidence (the smoking gun)
Route handlers work everywhere except the .well-known namespace. Run inside the cap-web container:
// returns 200 text/html — the SPA shell, NOT the workflow handler
fetch("http://127.0.0.1:3000/.well-known/workflow/v1/flow",
{method:"POST",headers:{"content-type":"application/json"},body:"{}"})
.then(async r => console.log(r.status, r.headers.get("content-type")))
| Request |
Result |
POST /api/upload/signed |
401 (handler runs ✅) |
POST /api/auth/providers |
400 (handler runs ✅) |
POST /.well-known/workflow/v1/flow |
200 text/html ❌ |
POST /.well-known/workflow/v1/step |
200 text/html ❌ |
POST /.well-known/appspecific/anything (nonexistent) |
200 text/html ❌ |
So the whole /.well-known/* namespace falls through to the app render — even a path with no route. The route handlers do exist in the build (/.next/server/app/.well-known/workflow/v1/flow/route.js) and are listed in app-paths-manifest.json; nothing shadows them (middleware manifest is empty; no .well-known rewrite in next.config.mjs). They simply never execute.
Because the self-call returns 200, the local queue's dispatch logs no error (it only logs on non-2xx), so the failure is completely silent.
Suspected cause & suggested fix
apps/web/package.json:
"build": "next build --turbopack",
"build:web": "next build --turbopack",
Turbopack's production/standalone build does not appear to serve app route handlers under a dot-prefixed top-level segment (.well-known). Suggested fix: build the web app with webpack (drop --turbopack), or have Turbopack emit/serve these routes correctly.
I'm validating a webpack rebuild of this exact image and will follow up / open a PR if it resolves it. Happy to provide the full .workflow-data run dump, manifests, or any other diagnostics.
Summary
On the self-hosted Docker image (
ghcr.io/capsoftware/cap-web:latest), every recording gets stuck on "Processing failed". Uploads succeed (segments +manifest.jsonland in the bucket), but the recording never finishes processing.Root cause: the Workflow DevKit control-plane routes under
/.well-known/workflow/v1/*are not served by their route handlers — they return the Next.js app/SPA HTML shell withHTTP 200. Because the workflow engine advances every durable step by making an HTTP self-call to/.well-known/workflow/v1/flow(and/step), and that call gets a200 text/htmlpage back instead of the handler, the workflow silently never advances. No error is logged; the run stayspendingforever.This appears to be a Next.js 16 + Turbopack standalone build issue:
apps/web/package.jsonbuilds withnext build --turbopack, and the entire.well-knownnamespace is unreachable at runtime in the standalone server.Environment
ghcr.io/capsoftware/cap-web:latest(built 2026-06-13, Next16.2.1,workflow@4.2.0-beta.73,@workflow/world-local@4.1.0-beta.46)docker-compose.yml(MySQL + MinIO + media-server + cap-web)desktopSegments(in-browser recorder)Reproduction
manifest.json(is_complete: true) upload to the bucket; the media-server is never called; the cap is shown as "Processing failed"..workflow-data/runs/*.jsonshows the run stuck at"status": "pending"(only arun_createdevent), andvideo_uploads.phasestaysprocessingwithprocessing_error = NULL.Evidence (the smoking gun)
Route handlers work everywhere except the
.well-knownnamespace. Run inside the cap-web container:POST /api/upload/signed401(handler runs ✅)POST /api/auth/providers400(handler runs ✅)POST /.well-known/workflow/v1/flow200 text/html❌POST /.well-known/workflow/v1/step200 text/html❌POST /.well-known/appspecific/anything(nonexistent)200 text/html❌So the whole
/.well-known/*namespace falls through to the app render — even a path with no route. The route handlers do exist in the build (/.next/server/app/.well-known/workflow/v1/flow/route.js) and are listed inapp-paths-manifest.json; nothing shadows them (middleware manifest is empty; no.well-knownrewrite innext.config.mjs). They simply never execute.Because the self-call returns
200, the local queue's dispatch logs no error (it only logs on non-2xx), so the failure is completely silent.Suspected cause & suggested fix
apps/web/package.json:Turbopack's production/standalone build does not appear to serve app route handlers under a dot-prefixed top-level segment (
.well-known). Suggested fix: build the web app with webpack (drop--turbopack), or have Turbopack emit/serve these routes correctly.I'm validating a webpack rebuild of this exact image and will follow up / open a PR if it resolves it. Happy to provide the full
.workflow-datarun dump, manifests, or any other diagnostics.