heygen-com/hyperframes · error · Error
BeginFrame probe timeout before ${label}
Error message
BeginFrame probe timeout before ${label} What it means
Thrown by the BeginFrame CDP probe's deadline guard in packages/aws-lambda/scripts/probe-beginframe.ts when the supplied deadline has already elapsed before the operation even starts. `awaitBeforeDeadline` computes `deadline - Date.now()` and fails fast rather than scheduling a setTimeout with a negative/zero delay. It exists to keep the standalone probe's total wall-clock inside Lambda's hard 15-minute ceiling.
Source
Thrown at packages/aws-lambda/scripts/probe-beginframe.ts:115
};
}
function readLaunchArgs(path: string): string[] {
const resolved = resolve(path);
const value: unknown = JSON.parse(readFileSync(resolved, "utf-8"));
if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) {
throw new Error(`--launch-args-json must contain a JSON string array: ${resolved}`);
}
return value;
}
async function awaitBeforeDeadline<T>(
operation: Promise<T>,
deadline: number,
label: string,
): Promise<T> {
const remainingMs = deadline - Date.now();
if (remainingMs <= 0) throw new Error(`BeginFrame probe timeout before ${label}`);
let timeout: ReturnType<typeof setTimeout> | undefined;
try {
return await Promise.race([
operation,
new Promise<never>((_, reject) => {
timeout = setTimeout(
() => reject(new Error(`BeginFrame probe timeout during ${label}`)),
remainingMs,
);
}),
]);
} finally {
if (timeout) clearTimeout(timeout);
}
}
/** Test-only export for the standalone probe's bounded-operation contract. */
export const _awaitBeforeDeadlineForTests = awaitBeforeDeadline;View on GitHub (pinned to c2996c8626)
Solutions
- Confirm the deadline passed to awaitBeforeDeadline is an absolute epoch-ms in the future (e.g. `Date.now() + budgetMs`), not a duration.
- Increase the probe budget if cold-start + Chromium extraction legitimately exceeds it.
- Run the probe on a warmer instance or pre-extract Chromium to shrink time-to-first-frame.
- Check for system clock skew between the process that computed the deadline and the one running the probe.
Example fix
// before await awaitBeforeDeadline(probeOp, 10_000, "beginframe"); // after await awaitBeforeDeadline(probeOp, Date.now() + 30_000, "beginframe");
Defensive patterns
Strategy: validation
Validate before calling
function remainingDeadlineMs(deadline: number): number {
const remaining = deadline - Date.now();
if (remaining <= 0) {
throw new Error(`deadline already expired: deadline=${deadline}, now=${Date.now()}`);
}
return remaining;
}
// call before awaitBeforeDeadline
const budget = remainingDeadlineMs(deadline); Try / catch
try {
await awaitBeforeDeadline(operation, deadline, label);
} catch (err) {
if (err instanceof Error && /BeginFrame probe timeout before/.test(err.message)) {
// deadline already elapsed — extend budget and retry once, or surface as a config error
}
throw err;
} Prevention
- Always pass an absolute epoch-ms deadline (Date.now() + budget), never a relative duration.
- Compute the deadline at the start of the probe, not before cold-start work that consumes the budget.
- Log `deadline - Date.now()` at probe entry so budget exhaustion is visible.
When it happens
Trigger: Calling `awaitBeforeDeadline(operation, deadline, label)` with a `deadline` whose epoch-ms value is <= `Date.now()` — i.e. the caller computed the deadline too early, passed an absolute timestamp from the wrong clock domain, or the probe was queued behind slow startup so the budget is already exhausted.
Common situations: Lambda cold start plus Chromium extraction consuming the entire probe budget; a CI runner whose wall clock drifted relative to the deadline passed in; passing a relative duration (e.g. `5000`) where an absolute epoch-ms was expected.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- beginFrame probe timeout before ${label}
- beginFrame screenshot returned ${bytes.length} bytes after $
- --executable-path requires a path
- --launch-args-json requires a path
- Unknown argument: ${arg}
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/dd939f22849b93aa.
Report an issue: GitHub.