heygen-com/hyperframes · warning · Error
--shot: nothing animates under '${scopeSelector}'. Nearest a
Error message
--shot: nothing animates under '${scopeSelector}'. Nearest animated elements: ${nearest || "(none)"}. What it means
Thrown by resolveScopedRequests when the --selector scope matched a real element (scopeExists === true) but no animated selectors were found underneath it — neither the scope element itself nor any descendant is in the animated-requests list. The message lists the nearest animated elements (up to 5) as diagnostic context so you can re-scope correctly.
Source
Thrown at packages/cli/src/commands/motionShot.ts:452
async function resolveScopedRequests(
page: import("puppeteer-core").Page,
requests: ShotRequest[],
scopeSelector: string,
): Promise<ShotRequest[]> {
const resolved = await resolveScopeInBrowser(
page,
scopeSelector,
requests.map((r) => r.selector),
);
if (!resolved.scopeExists) {
throw new Error(`--shot: --selector '${scopeSelector}' matched no element.`);
}
if (resolved.selectors.length === 0) {
const nearest = requests
.slice(0, 5)
.map((r) => r.selector)
.join(", ");
throw new Error(
`--shot: nothing animates under '${scopeSelector}'. Nearest animated elements: ${nearest || "(none)"}.`,
);
}
return resolved.selectors.map((selector) => ({ selector }));
}
// In-tick capture: seek the timeline (fires the composition's onUpdate render
// synchronously via the shared window.__hfSeekAllAdapters) + nudge the
// three-adapter, then drawImage every <canvas> onto an offscreen canvas in the
// SAME tick — before the browser clears the GL drawing buffer (works without
// preserveDrawingBuffer; page.screenshot can't see the GL buffer here).
function captureGhostFrame(page: import("puppeteer-core").Page, t: number): Promise<string> {
return page.evaluate(async (tt: number) => {
await (
window as unknown as { __hfSeekAllAdapters?: (time: number) => Promise<void> }
).__hfSeekAllAdapters?.(tt);
const root = (document.querySelector("[data-composition-id]") ?? document.body) as HTMLElement;
const rb = root.getBoundingClientRect();View on GitHub (pinned to c2996c8626)
Solutions
- Re-scope to one of the nearest animated elements listed in the error message
- Drop --selector to let the shot sample all detected animated elements
- Verify the element you expect to animate actually has a registered timeline (window.__timelines)
- Ensure GSAP timelines are registered on window.__timelines so they are detected as animated
Example fix
// before — static wrapper has no animated children hyperframes shot --selector '.static-clip' out.png // after — scope the element that actually animates hyperframes shot --selector '.animated-child' out.png
Defensive patterns
Strategy: validation
Validate before calling
// After bundling, check the scope has animated descendants:
const animated = await page.evaluate((scope: string) => {
const root = document.querySelector(scope);
if (!root) return { exists: false, animated: 0 };
const timelines = Object.keys((window as any).__timelines ?? {});
const animated = timelines.filter(sel => {
const el = document.querySelector(sel);
return el && (el === root || root.contains(el));
}).length;
return { exists: true, animated };
}, scopeSelector);
if (animated.animated === 0) {
// pick a different scope or drop --selector
} Prevention
- Scope to elements known to carry registered timelines (window.__timelines)
- If unsure, omit --selector to sample all animated elements
When it happens
Trigger: Scoping to a static wrapper element (e.g. a .clip container) that has no animated children, or whose animated children are outside the request set. The scope exists but carries no motion sampled by the shot.
Common situations: Targeting a layout container instead of the animated child. Compositions where animation is on a sibling rather than a descendant. Selectors that match a decorative wrapper with no tweens.
Related errors
- --shot: --selector '${scopeSelector}' matched no element.
- --ghost renders a canvas/WebGL motion trail, but this compos
- --source must be 'sparticuz' or 'chrome-headless-shell' (got
- Unknown flag: ${arg}
- --executable-path requires a path
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/cdc16e3d833c21d2.
Report an issue: GitHub.