heygen-com/hyperframes · error · AddError
install-failed
install-failed
Error message
Install failed: ${err instanceof Error ? err.message : String(err)} What it means
AddError with code 'install-failed', thrown by installAll as a catch-all wrapper around the per-item installItem loop. Any error from writing files, creating directories, or item-level validation is re-wrapped so the command surfaces a consistent exit code; the original error message is preserved in the AddError message. Because the installer validates every target before writing, a mid-loop failure still leaves earlier items written.
Source
Thrown at packages/cli/src/commands/add.ts:194
// Install a topologically-ordered plan (dependencies first, requested item
// last). The installer validates every target before any write; a failure on
// any item surfaces as an install-failed AddError. Returns all written paths.
async function installAll(
installPlan: RegistryItem[],
destDir: string,
baseUrl: string | undefined,
force: boolean,
): Promise<{ written: string[]; preserved: string[] }> {
const written: string[] = [];
const preserved: string[] = [];
try {
for (const planItem of installPlan) {
const result = await installItem(planItem, { destDir, baseUrl, force });
written.push(...result.written);
preserved.push(...result.preserved);
}
} catch (err) {
throw new AddError(
`Install failed: ${err instanceof Error ? err.message : String(err)}`,
"install-failed",
);
}
return { written, preserved };
}
export async function runAdd(opts: RunAddArgs): Promise<RunAddResult> {
const projectDir = resolve(opts.projectDir);
// 1. Load (or write default) project config.
let config = loadProjectConfig(projectDir);
const hasConfig = existsSync(projectConfigPath(projectDir));
if (!hasConfig && existsSync(resolve(projectDir, "index.html"))) {
writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
config = DEFAULT_PROJECT_CONFIG;
}
View on GitHub (pinned to c2996c8626)
Solutions
- Read the inner message in 'Install failed: <inner>' — it names the exact file and filesystem error.
- Re-run with --force if the cause is an existing target you intend to overwrite.
- Fix permissions on the project directory (chown/chmod) or run from a location you own.
- Free disk space or clear the registry cache if the inner error is ENOSPC.
Example fix
# before: existing file blocks the install $ hyperframes add my-block # install-failed: EEXIST ... # after: explicitly overwrite $ hyperframes add my-block --force
Defensive patterns
Strategy: try-catch
Validate before calling
import { access, constants } from 'node:fs/promises';
async function assertWritable(dir: string) {
await access(dir, constants.W_OK);
}
await assertWritable(resolve(projectDir)); Try / catch
try {
await runAdd(opts);
} catch (err) {
if (err instanceof AddError && err.code === 'install-failed') {
if (/EEXIST/.test(err.message)) opts.force = true; // retry with --force
else throw err;
}
} Prevention
- Confirm write permission on the project directory before invoking add.
- Pass --force only when you intend to overwrite existing targets.
- Free disk space in CI and clear the registry cache periodically.
When it happens
Trigger: Filesystem permission denied on destDir, a target path collision that force=false refuses to overwrite, disk full, an EACCES/EPERM on the registry cache, or installItem throwing on a malformed item manifest.
Common situations: Running without write permission to the project (read-only mount, root-owned dir); a pre-existing file at the target without --force; symlink or case-collision on case-insensitive filesystems; full disk in CI.
Related errors
- incompatible-cli
- unknown-item
- example-type
- LUT file not found for "${cell.label}": ${sourcePath}
- Reference frame not found: ${framePath}
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/dc9e298af1204da1.
Report an issue: GitHub.