heygen-com/hyperframes · error · Error
Media analysis requires a local project asset; freeze remote
Error message
Media analysis requires a local project asset; freeze remote media with media-use first
What it means
Thrown by resolveMediaTreatmentSource when the selected media element's src is a remote URL (http/https) or an inline data: URI. The --analyze path must read raw file bytes from disk to measure color/luma/HDR metadata, so it cannot operate on media that lives outside the project. The message directs you to first materialize the asset locally via the media-use command.
Source
Thrown at packages/cli/src/commands/media-treatment.ts:497
function mediaSourceForElement(element: Element): string {
const src =
element.getAttribute("src") ??
(element.tagName.toLowerCase() === "video"
? element.querySelector("source")?.getAttribute("src")
: null);
if (!src) throw new Error("Selected media has no analyzable src");
return src;
}
export function resolveMediaTreatmentSource(
projectDir: string,
compositionFile: string,
source: string,
): string {
const sourceUrl = source.trim();
if (!sourceUrl) throw new Error("Selected media has no analyzable local src");
if (isRemoteOrInlineUrl(sourceUrl)) {
throw new Error(
"Media analysis requires a local project asset; freeze remote media with media-use first",
);
}
const cleanSource = cleanAssetUrl(sourceUrl);
if (!cleanSource) throw new Error("Selected media has no analyzable local src");
const projectRelative = cleanSource.startsWith("/")
? cleanSource
: rewriteAssetPath(compositionFile, cleanSource, (path) => existsSync(join(projectDir, path)));
const asset = resolveExistingLocalAsset(projectDir, projectRelative);
if (!asset) throw new Error(`Media file not found: ${source}`);
return asset.resolved;
}
function parseGrading(raw: string | undefined, apply: boolean, clear: boolean): unknown {
if (clear) {
if (raw !== undefined || apply) {
throw new Error("Use either --apply with --grading or --clear, not both");
}View on GitHub (pinned to c2996c8626)
Solutions
- Run `hyperframes media-use <remote-url>` to download/freeze the asset into the project, which rewrites the src to a local path
- Re-run `hyperframes media-treatment --selector '#hero' --analyze` after the src is local
- If you intentionally want to keep the remote src, skip --analyze and use --capabilities or --apply with a known preset instead
- Programmatically, check isRemoteOrInlineUrl(source) before calling resolveMediaTreatmentSource and pre-freeze or skip analysis
Example fix
// before <img src="https://cdn.example.com/hero.jpg" id="hero"> // freeze the remote asset locally first // hyperframes media-use https://cdn.example.com/hero.jpg // src is now a local project path; analyze succeeds hyperframes media-treatment --selector '#hero' --analyze
Defensive patterns
Strategy: validation
Validate before calling
import { isRemoteOrInlineUrl } from '@hyperframes/parsers/asset-resolution';
function assertLocalAssetForAnalysis(source: string): void {
if (isRemoteOrInlineUrl(source.trim())) {
throw new Error('Source is remote/inline — run `hyperframes media-use` to freeze it locally first.');
}
}
// call before resolveMediaTreatmentSource
assertLocalAssetForAnalysis(source); Try / catch
try {
const path = resolveMediaTreatmentSource(projectDir, compositionFile, source);
} catch (e) {
if (e instanceof Error && /freeze remote media/.test(e.message)) {
// run media-use, then retry
} else throw e;
} Prevention
- Always run media-use on remote assets before invoking --analyze
- In agent loops, check isRemoteOrInlineUrl(source) and branch to the freeze step automatically
When it happens
Trigger: Running `hyperframes media-treatment --selector '#hero' --analyze` where the matched <img>/<video> has src="https://cdn.example.com/hero.jpg" or src="data:image/png;base64,...". Also reached programmatically by calling resolveMediaTreatmentSource with a source string that isRemoteOrInlineUrl() returns true for.
Common situations: Compositions that reference stock photos, CDN-hosted video, or base64-embedded images. Agents that skip the media-use freeze step and jump straight to --analyze. Migrating a composition from remote to local assets but forgetting to update the analyze workflow.
Related errors
- --selector-index must be a non-negative integer
- Use either --apply with --grading or --clear, not both
- --grading requires --apply
- --apply requires --grading <json>
- Could not parse --grading JSON: ${normalizeErrorMessage(erro
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/4cfd1040fb479eb6.
Report an issue: GitHub.