heygen-com/hyperframes · error

Could not determine composition duration — no layout samples

Error message

Could not determine composition duration — no layout samples run

What it means

Thrown inside buildSampleGrid when layoutSamples (the merge of base layout samples, transition times, caption samples, and frame samples) is empty. buildLayoutSampleTimes and gateSampleTimes both return [] when duration is not finite or <= 0, so the practical root cause is that driver.getDuration() returned 0, NaN, Infinity, or a negative number. Without sample times the audit grid cannot run at all.

Source

Thrown at packages/cli/src/utils/checkPipeline.ts:153

    at: options.at,
  });
  const transitions = options.atTransitions
    ? buildTransitionSampleTimes({
        duration,
        boundaries: await driver.getTransitionBoundaries(),
        cap: options.maxTransitionSamples,
      })
    : { times: [], dropped: 0 };
  const captionSamples = options.captionZone
    ? gateSampleTimes(duration, options.captionZone.seek, 1)
    : [];
  const frameSamples = options.frameCheck
    ? gateSampleTimes(duration, options.frameCheck.seek, 0.5)
    : [];
  const auditSamples = mergeSampleTimes(baseSamples, transitions.times);
  const layoutSamples = mergeSampleTimes(auditSamples, captionSamples, frameSamples);
  if (layoutSamples.length === 0) {
    throw new Error("Could not determine composition duration — no layout samples run");
  }
  return {
    duration,
    layoutSamples,
    captionSamples,
    frameSamples,
    transitionSamples: transitions.times,
    transitionSamplesDropped: transitions.dropped,
    contrastSamples: options.contrast ? selectContrastTimes(auditSamples) : [],
  };
}

interface MotionPlan {
  times: number[];
  selectors: string[];
  livenessScopes: string[];
  preflightIssues: AnchoredLayoutIssue[];
}

View on GitHub (pinned to c2996c8626)

Solutions

  1. Ensure the composition declares a duration: set data-duration on the composition root or register a paused GSAP timeline whose totalDuration() is positive.
  2. Open the composition in a browser and confirm window.__hyperframes.getDuration() returns a positive finite number.
  3. If using a custom CheckAuditDriver, verify getDuration() resolves to a positive finite value before runAuditGrid.
  4. Check that options.samples is >= 1 (DEFAULT_CHECK_OPTIONS.samples is 9).

Example fix

<!-- before: no duration, getDuration returns 0 -->
<div data-composition-id="root">
  <!-- clips with no aggregate duration -->
</div>
<!-- after -->
<div data-composition-id="root" data-duration="10">
  <div class="clip" data-start="0" data-end="10">...</div>
</div>
Defensive patterns

Strategy: validation

Validate before calling

const duration = await driver.getDuration();
if (!Number.isFinite(duration) || duration <= 0) {
  throw new Error(`Composition duration is invalid (${duration}); set data-duration on the root or register a paused GSAP timeline.`);
}
// safe to call runAuditGrid now

Type guard

function hasPositiveFiniteDuration(d: unknown): d is number {
  return typeof d === 'number' && Number.isFinite(d) && d > 0;
}

Try / catch

try {
  return await runAuditGrid(driver, options, motion);
} catch (err) {
  if (err instanceof Error && /no layout samples run/.test(err.message)) {
    // duration was 0/NaN — fix the composition's data-duration/timeline, then retry
    console.error('Audit aborted: composition reported no duration. Add data-duration to the root.');
    return emptyBrowserResult();
  }
  throw err;
}

Prevention

When it happens

Trigger: The browser driver reported a composition duration of 0, NaN, or negative — typically because the GSAP timeline has no duration attribute, the composition's data-duration is unset/zero, or the page failed to expose a seekable timeline so getDuration fell back to 0. Also reachable if options.samples is 0 and no transition/caption/frame samples fill the grid.

Common situations: A composition that autoplays a CSS animation with no data-duration (the runtime cannot measure total duration); a draft index.html with no clip/timeline; a mock driver in tests returning 0; a page where the timeline throws during initialization so getDuration returns a sentinel.

Related errors


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