heygen-com/hyperframes · critical · Error
Unsafe target "${target}": path segments may not contain "..
Error message
Unsafe target "${target}": path segments may not contain "..". What it means
Thrown by assertSafeTarget when a registry file target contains a '..' path segment. The regex matches '..' between separators or at the start/end, catching both Unix and Windows backslash traversal attempts. This blocks escapes like '../../etc' that would resolve outside destDir.
Source
Thrown at packages/cli/src/registry/installer.ts:99
onDisk: Buffer | string,
): boolean {
const installed = record[target];
if (!installed) return true;
return installed !== digest(onDisk);
}
/**
* Reject target paths that would escape `destDir`. Mirrors the pattern check
* in `packages/core/schemas/registry-item.json#files.items.target`, but runs at
* install time so a registry that bypasses schema validation still can't write
* outside the project.
*/
export function assertSafeTarget(destDir: string, target: string): void {
if (isAbsolute(target)) {
throw new Error(`Unsafe target "${target}": absolute paths are not allowed.`);
}
if (/(^|[/\\])\.\.([/\\]|$)/.test(target)) {
throw new Error(`Unsafe target "${target}": path segments may not contain "..".`);
}
if (/^[A-Za-z]:[/\\]/.test(target)) {
throw new Error(`Unsafe target "${target}": Windows drive letters are not allowed.`);
}
const resolved = resolve(destDir, target);
const rel = relative(resolve(destDir), resolved);
if (rel.startsWith("..") || isAbsolute(rel)) {
throw new Error(`Unsafe target "${target}": resolves outside destDir ${destDir}.`);
}
}
function isInstalledRegistryBlockComposition(item: RegistryItem, file: FileTarget): boolean {
return (
item.type === "hyperframes:block" &&
file.type === "hyperframes:composition" &&
file.target.toLowerCase().endsWith(".html")
);
}View on GitHub (pinned to c2996c8626)
Solutions
- Flatten the target so it stays within destDir (no '..' segments)
- If sharing across projects is intended, install the asset into each project separately
- Validate targets against the registry-item.json schema before publishing
- Audit the item's file list before installing
Example fix
// before
{ "target": "../../shared/x.html" }
// after
{ "target": "shared/x.html" } Defensive patterns
Strategy: validation
Validate before calling
function noTraversal(target: string): boolean {
return !/(^|[/\\])\.\.([/\\]|$)/.test(target);
} Type guard
function isNonTraversalTarget(target: string): boolean {
return !/(^|[/\\])\.\.([/\\]|$)/.test(target);
} Prevention
- Never use '..' in registry file targets
- Keep targets flat under destDir
- Run the schema validator before publishing registry items
When it happens
Trigger: assertSafeTarget runs during install; target matches /(^|[/\\])\.\.([/\\]|$)/ (e.g. '../secret', 'a/../../b', '..\\windows') → throw at installer.ts:99.
Common situations: A registry item trying to (or accidentally) write above the project root; cross-platform targets mixing '/' and '\'; an item authored to 'share' a file with a sibling project via relative traversal; a malicious registry.
Related errors
- Unsafe target "${target}": absolute paths are not allowed.
- Unsafe target "${target}": Windows drive letters are not all
- Unsafe target "${target}": resolves outside destDir ${destDi
- --file must be an HTML file inside the project
- Unknown effect type: ${type}
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/54cf06bee285f69b.
Report an issue: GitHub.