{"record":{"id":"df3a29a0331b1344","repo":"heygen-com/hyperframes","slug":"selected-media-has-no-analyzable-local-src","errorCode":null,"errorMessage":"Selected media has no analyzable local src","messagePattern":"Selected media has no analyzable local src","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/media-treatment.ts","lineNumber":495,"sourceCode":"}\n\nfunction mediaSourceForElement(element: Element): string {\n  const src =\n    element.getAttribute(\"src\") ??\n    (element.tagName.toLowerCase() === \"video\"\n      ? element.querySelector(\"source\")?.getAttribute(\"src\")\n      : null);\n  if (!src) throw new Error(\"Selected media has no analyzable src\");\n  return src;\n}\n\nexport function resolveMediaTreatmentSource(\n  projectDir: string,\n  compositionFile: string,\n  source: string,\n): string {\n  const sourceUrl = source.trim();\n  if (!sourceUrl) throw new Error(\"Selected media has no analyzable local src\");\n  if (isRemoteOrInlineUrl(sourceUrl)) {\n    throw new Error(\n      \"Media analysis requires a local project asset; freeze remote media with media-use first\",\n    );\n  }\n  const cleanSource = cleanAssetUrl(sourceUrl);\n  if (!cleanSource) throw new Error(\"Selected media has no analyzable local src\");\n  const projectRelative = cleanSource.startsWith(\"/\")\n    ? cleanSource\n    : rewriteAssetPath(compositionFile, cleanSource, (path) => existsSync(join(projectDir, path)));\n  const asset = resolveExistingLocalAsset(projectDir, projectRelative);\n  if (!asset) throw new Error(`Media file not found: ${source}`);\n  return asset.resolved;\n}\n\nfunction parseGrading(raw: string | undefined, apply: boolean, clear: boolean): unknown {\n  if (clear) {\n    if (raw !== undefined || apply) {","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/cli/src/commands/media-treatment.ts#L477-L513","documentation":"Thrown by resolveMediaTreatmentSource() in packages/cli/src/commands/media-treatment.ts:495. It trims the src and throws this specific message when the result is empty, or (line 502) when cleanAssetUrl returns null. Analysis only operates on local project assets — remote/inline URLs are rejected separately. This is the empty/unresolvable-local-src branch.","triggerScenarios":"The element's src, after trim, is empty; or cleanAssetUrl cannot extract a usable local path from it (e.g. blank, malformed, or an inline asset URL that doesn't clean to a filesystem path). Remote URLs hit a different, more specific error.","commonSituations":"Empty src attribute; src containing only whitespace; src that's an inline/blob/data placeholder; src that cleanAssetUrl rejects as non-local before the remote check fires.","solutions":["Give the element a real local project-relative src (e.g. 'assets/hero.mp4').","Confirm the asset file exists under the project dir; if remote, run `hyperframes media-use` to freeze it locally first.","Remove empty/placeholder src attributes before analysis."],"exampleFix":"<!-- before -->\n<video id=\"hero\" src=\"\"></video>\n<!-- after -->\n<video id=\"hero\" src=\"assets/hero.mp4\"></video>","handlingStrategy":"validation","validationCode":"import { cleanAssetUrl, isRemoteOrInlineUrl } from '@hyperframes/parsers/asset-resolution';\n\nfunction isAnalyzableLocalSrc(src: string): boolean {\n  const trimmed = src.trim();\n  if (!trimmed || isRemoteOrInlineUrl(trimmed)) return false;\n  return cleanAssetUrl(trimmed) !== null;\n}","typeGuard":"function isAnalyzableLocalSrc(src: string): boolean {\n  const trimmed = src.trim();\n  if (!trimmed) return false;\n  if (isRemoteOrInlineUrl(trimmed)) return false;\n  return cleanAssetUrl(trimmed) !== null;\n}","tryCatchPattern":"try {\n  resolveMediaTreatmentSource(projectDir, compositionFile, source);\n} catch (error) {\n  if (/no analyzable local src/.test(String(error))) {\n    // set a real local asset path or freeze remote media first\n    throw new Error('src is empty/inline/remote — point at a local project asset or run media-use first');\n  }\n  throw error;\n}","preventionTips":["Use local project-relative asset paths for media you intend to analyze.","Freeze remote/inline media locally with `hyperframes media-use` before --analyze.","Reject empty/placeholder src attributes before analysis."],"tags":["media","validation","filesystem","media-treatment"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}