ruvnet/ruflo · error · ExtractionError
archive did not contain the expected binary at its root: ${b
Error message
archive did not contain the expected binary at its root: ${binaryNameInArchive()} What it means
Error "archive did not contain the expected binary at its root: ${binaryNameInArchive()}" thrown in ruvnet/ruflo.
Source
Thrown at v3/@claude-flow/cli/src/proxy/install.ts:153
assetBytes: assets.archiveBytes,
assetFilename: assets.archiveFilename,
});
log(`Verified — sha256 ${sha256.slice(0, 16)}…`);
// fetchReleaseAssets's dev (gh) path already wrote the archive to workDir
// under archiveFilename; ensure it's there regardless of source so
// extraction always has a real file to operate on.
const archivePath = path.join(workDir, archiveFilename);
if (!fs.existsSync(archivePath)) {
fs.writeFileSync(archivePath, assets.archiveBytes);
}
const extractDir = path.join(workDir, 'extracted');
await extractArchive(archivePath, extractDir, releaseArchiveExtension(triple));
const extractedBinaryPath = path.join(extractDir, binaryNameInArchive());
if (!fs.existsSync(extractedBinaryPath)) {
throw new ExtractionError(`archive did not contain the expected binary at its root: ${binaryNameInArchive()}`);
}
// Defense in depth: confirm the extracted binary genuinely resolves
// inside extractDir (catches a symlink swap or similar), even though
// we only ever read one specific expected relative path, never an
// archive-listed one (so "zip slip" via arbitrary archive paths isn't
// reachable here in the first place).
const { PathValidator } = await import('@claude-flow/security');
const validator = new PathValidator({ allowedPrefixes: [extractDir] });
const validation = await validator.validate(extractedBinaryPath);
if (!validation.isValid) {
throw new ExtractionError(`extracted binary path failed validation: ${validation.errors.join('; ') || 'unknown'}`);
}
const finalPath = proxyBinaryPath();
fs.mkdirSync(path.dirname(finalPath), { recursive: true, mode: 0o700 });
const tmp = `${finalPath}.tmp`;
fs.copyFileSync(extractedBinaryPath, tmp);View on GitHub (pinned to 6b01dc5a68)
When it happens
Trigger: Thrown at v3/@claude-flow/cli/src/proxy/install.ts:153 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/add42de5e916f1fe.
Report an issue: GitHub.