{"record":{"id":"dd939f22849b93aa","repo":"heygen-com/hyperframes","slug":"beginframe-probe-timeout-before-label","errorCode":null,"errorMessage":"BeginFrame probe timeout before ${label}","messagePattern":"BeginFrame probe timeout before (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/aws-lambda/scripts/probe-beginframe.ts","lineNumber":115,"sourceCode":"  };\n}\n\nfunction readLaunchArgs(path: string): string[] {\n  const resolved = resolve(path);\n  const value: unknown = JSON.parse(readFileSync(resolved, \"utf-8\"));\n  if (!Array.isArray(value) || !value.every((item) => typeof item === \"string\")) {\n    throw new Error(`--launch-args-json must contain a JSON string array: ${resolved}`);\n  }\n  return value;\n}\n\nasync function awaitBeforeDeadline<T>(\n  operation: Promise<T>,\n  deadline: number,\n  label: string,\n): Promise<T> {\n  const remainingMs = deadline - Date.now();\n  if (remainingMs <= 0) throw new Error(`BeginFrame probe timeout before ${label}`);\n  let timeout: ReturnType<typeof setTimeout> | undefined;\n  try {\n    return await Promise.race([\n      operation,\n      new Promise<never>((_, reject) => {\n        timeout = setTimeout(\n          () => reject(new Error(`BeginFrame probe timeout during ${label}`)),\n          remainingMs,\n        );\n      }),\n    ]);\n  } finally {\n    if (timeout) clearTimeout(timeout);\n  }\n}\n\n/** Test-only export for the standalone probe's bounded-operation contract. */\nexport const _awaitBeforeDeadlineForTests = awaitBeforeDeadline;","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/aws-lambda/scripts/probe-beginframe.ts#L97-L133","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait awaitBeforeDeadline(probeOp, 10_000, \"beginframe\");\n// after\nawait awaitBeforeDeadline(probeOp, Date.now() + 30_000, \"beginframe\");","handlingStrategy":"validation","validationCode":"function remainingDeadlineMs(deadline: number): number {\n  const remaining = deadline - Date.now();\n  if (remaining <= 0) {\n    throw new Error(`deadline already expired: deadline=${deadline}, now=${Date.now()}`);\n  }\n  return remaining;\n}\n// call before awaitBeforeDeadline\nconst budget = remainingDeadlineMs(deadline);","typeGuard":null,"tryCatchPattern":"try {\n  await awaitBeforeDeadline(operation, deadline, label);\n} catch (err) {\n  if (err instanceof Error && /BeginFrame probe timeout before/.test(err.message)) {\n    // deadline already elapsed — extend budget and retry once, or surface as a config error\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["timeout","lambda","probe","deadline","beginframe"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}