heygen-com/hyperframes · error · Error

background preview did not become ready; see ${logPath}

Error message

background preview did not become ready; see ${logPath}

What it means

Thrown when the detached background preview server fails to become ready within the polling window. The lifecycle code writes a session file once a matching server answers the readiness scan; if that never happens it kills the spawned pid and throws, pointing at the log file the child's stdio was routed to for diagnosis.

Source

Thrown at packages/cli/src/commands/previewLifecycle.ts:250

      existing,
      dependencies.forceNew === true,
      dependencies.browserGpuMode,
    );
    if (server) {
      const session = {
        pid,
        port: server.port,
        projectDir: resolve(projectDir),
        logPath,
      };
      writePreviewSession(session, stateHome);
      return { type: "started", ...session };
    }
    await sleep(200);
  }

  (dependencies.kill ?? stopProcess)(pid);
  throw new Error(`background preview did not become ready; see ${logPath}`);
}

export async function stopBackgroundPreview(
  projectDir: string,
  startPort: number,
  dependencies: LifecycleDependencies = {},
): Promise<boolean> {
  const scan = dependencies.scan ?? scanActiveServers;
  const stateHome = dependencies.stateHome ?? defaultStateHome();
  const saved = readPreviewSession(projectDir, stateHome);
  const scanStart = saved?.port ?? startPort;
  const server = matchingServer(await scan(scanStart), projectDir);
  // A saved PID can be reused after a crashed preview, so only trust it while
  // a currently reachable server proves this exact project is still running.
  const pid = Number(server ? (server.pid ?? saved?.pid) : undefined);
  if (!Number.isInteger(pid) || pid <= 0) {
    removePreviewSession(projectDir, stateHome);
    return false;

View on GitHub (pinned to c2996c8626)

Solutions

  1. Read the referenced logPath file — the child's stdout/stderr were redirected there
  2. Ensure the start port is free: stop other preview servers (`hyperframes preview --stop`) or pick another port
  3. Run the preview in the foreground (`hyperframes preview`) to see startup errors directly
  4. Check the composition lints: `npx hyperframes lint`
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await startBackgroundPreview(projectDir, port, {...});
} catch (e) {
  if (e.message.includes("did not become ready")) {
    const log = readFileSync(e.message.match(/see (.*)$/)?.[1] ?? "", "utf8");
    console.error(log); // surface the child's startup error
  }
  throw e;
}

Prevention

When it happens

Trigger: startBackgroundPreview spawns the child, then loops polling scanActiveServers until the server appears (200ms sleep between attempts). If the attempt budget is exhausted the pid is stopped and this error is raised at previewLifecycle.ts:250.

Common situations: The preview server crashed during startup (port in use, missing project files, a composition syntax error) so it never answers; the chosen start port is firewalled; heavy load made startup exceed the retry budget; a stale lock or bound port from a previous run.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/bc943fff3950ecda. Report an issue: GitHub.