diff --git a/packages/cli/src/server/studioServer.ts b/packages/cli/src/server/studioServer.ts index 5e415f9ab..8c7ae9b0c 100644 --- a/packages/cli/src/server/studioServer.ts +++ b/packages/cli/src/server/studioServer.ts @@ -508,6 +508,22 @@ export function createStudioServer(options: StudioServerOptions): StudioServer { }); }); + // ── Pre-flight checks for render ──────────────────────────────────────── + // Intercept render requests before they reach the shared API so we can + // fail fast with an actionable hint instead of burning through the entire + // capture pipeline before hitting "spawn ffmpeg ENOENT" at encode. + let cachedFFmpegPath: string | undefined; + app.post("/api/projects/:id/render", async (c, next) => { + const { findFFmpeg, getFFmpegInstallHint } = await import("../browser/ffmpeg.js"); + if (!cachedFFmpegPath) { + cachedFFmpegPath = findFFmpeg(); + } + if (!cachedFFmpegPath) { + return c.json({ error: "FFmpeg not found", hint: getFFmpegInstallHint() }, 503); + } + return next(); + }); + // Mount the shared studio API at /api. // Use fetch() forwarding (not .route()) so the sub-app sees paths without // the /api prefix — the shared module's path extraction uses c.req.path.