heygen-com/hyperframes · error · Error

Composition file not found: ${fileArg}

Error message

Composition file not found: ${fileArg}

What it means

Thrown by resolveMutationFile when the --file path passes the inside-project and .html checks but does not exist on disk (existsSync returns false). The file argument (as written by the user, not the resolved path) is echoed in the message.

Source

Thrown at packages/cli/src/commands/media-treatment.ts:579

  ].some(Boolean);
  if (hasMutationOption) throw new Error("--capabilities cannot be combined with mutation options");
  if (args.all === true && capability)
    throw new Error("Use either --all or --capability, not both");

  let capabilities: unknown = getMediaTreatmentCapabilityOverview();
  if (args.all === true) capabilities = getHfColorGradingCapabilities();
  else if (capability) capabilities = getMediaTreatmentCapabilityDetail(capability);
  console.log(JSON.stringify(withMeta({ ok: true, capabilities }), null, 2));
}

function resolveMutationFile(args: MediaTreatmentCommandArgs) {
  const project = resolveProject(readOptionalString(args.project));
  const fileArg = readOptionalString(args.file) ?? "index.html";
  const filePath = resolve(project.dir, fileArg);
  if (!isPathInside(filePath, project.dir) || !filePath.toLowerCase().endsWith(".html")) {
    throw new Error("--file must be an HTML file inside the project");
  }
  if (!existsSync(filePath)) throw new Error(`Composition file not found: ${fileArg}`);
  return { project, filePath };
}

function analyzeTarget(args: MediaTreatmentCommandArgs) {
  const { project, filePath } = resolveMutationFile(args);
  const selector = readOptionalString(args.selector);
  if (!selector) throw new Error("--selector is required");
  if (
    readOptionalString(args.grading) ||
    args.clear === true ||
    args.apply === true ||
    args["dry-run"] === true
  ) {
    throw new Error("--analyze cannot be combined with mutation options");
  }
  const selectorIndex = parseSelectorIndex(readOptionalString(args["selector-index"]));
  const { element, tag } = selectMediaElement(
    readFileSync(filePath, "utf8"),

View on GitHub (pinned to c2996c8626)

Solutions

  1. List the project directory to find the correct HTML file name
  2. Use the actual entry file: `--file <correct-name>.html`
  3. If using the default, ensure index.html exists or pass the real entry explicitly
  4. Create the composition file if it should exist

Example fix

// before
hyperframes media-treatment --file missing.html --selector '#hero' --apply
// after — use the file that exists
hyperframes media-treatment --file index.html --selector '#hero' --apply
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
import { resolve } from 'node:path';

function assertCompositionExists(projectDir: string, fileArg: string): void {
  if (!existsSync(resolve(projectDir, fileArg))) {
    throw new Error(`Composition file not found: ${fileArg}`);
  }
}

Prevention

When it happens

Trigger: Passing `--file missing.html` or `--file compositions/old-name.html` where the file was renamed or never created. Defaulting to index.html when the project uses a different entry name.

Common situations: Renamed composition files. Wrong default assumption (project uses scene.html not index.html). Typo in the filename. File exists in a different subdirectory.

Related errors


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