{"record":{"id":"efc29e9cc9c164fd","repo":"heygen-com/hyperframes","slug":"beginframe-probe-timeout-before-label-efc29e","errorCode":null,"errorMessage":"beginFrame probe timeout before ${label}","messagePattern":"beginFrame probe timeout before (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/engine/src/services/browserManager.ts","lineNumber":262,"sourceCode":" */\ninterface BeginFrameProbeResult {\n  supported: boolean;\n  detail: string;\n  durationMs: number;\n}\n\nconst BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS = 10;\nconst BEGINFRAME_PROBE_TIMEOUT_MS = 2000;\nconst BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS = 250;\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) {\n    throw new Error(`beginFrame probe timeout before ${label}`);\n  }\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\nasync function settleWithin(operation: Promise<unknown>, timeoutMs: number): Promise<boolean> {","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/engine/src/services/browserManager.ts#L244-L280","documentation":"Thrown by awaitBeforeDeadline() when the remaining time before a shared deadline has already elapsed (remainingMs <= 0). The beginFrame capability probe uses a single 2-second budget (BEGINFRAME_PROBE_TIMEOUT_MS) across multiple sequential CDP operations (domain enable, warm-up, screenshot retries). If earlier operations consumed the entire budget, a later step discovers no time remains and throws immediately.","triggerScenarios":"awaitBeforeDeadline(operation, deadline, label) is called as part of the beginFrame probe sequence. The deadline was set to Date.now() + 2000ms at probe start. A previous CDP call (e.g., HeadlessExperimental.enable or the first screenshot attempt) took long enough that the deadline has passed by the time this step begins.","commonSituations":"The headless Chrome instance is slow to respond (cold start, resource-constrained container, shared CI runner). The beginFrame domain exists but is sluggish. A previous screenshot retry burned most of the budget. The probe runs during heavy system load.","solutions":["Increase BEGINFRAME_PROBE_TIMEOUT_MS if the probe is timing out on slow but functional setups.","Ensure the Chrome process has adequate CPU/memory — containers with <1 CPU core are prone to this.","Pre-warm the Chrome instance before running the probe (e.g., load a simple page first).","If beginFrame is not supported, the probe result is 'supported: false' — verify the Chrome build includes HeadlessExperimental support."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await probeBeginFrameSupport(browser);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('beginFrame probe timeout')) {\n    // treat as unsupported; fall back to non-beginFrame capture\n  }\n  throw err;\n}","preventionTips":["Ensure Chrome has adequate CPU/memory before probing (>= 1 CPU core, >= 512MB RAM).","Pre-warm the Chrome instance with a simple page load before running the probe.","Treat probe timeout as 'beginFrame not supported' and fall back gracefully.","Increase BEGINFRAME_PROBE_TIMEOUT_MS for known-slow environments."],"tags":["browser","beginframe","timeout","performance","probe"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}