ruvnet/ruflo · error · Error
Failed to pack: ${error}
Error message
Failed to pack: ${error} What it means
Publisher.pack() runs `npm pack` (optionally with --pack-destination outputDir) and re-wraps any failure as 'Failed to pack: <cause>'. The underlying cause is visible in the wrapped message: npm missing from PATH, no package.json in cwd, or a pack-destination directory that does not exist.
Source
Thrown at v3/@claude-flow/deployment/src/publisher.ts:189
}
}
/**
* Pack package to tarball
*/
async pack(outputDir?: string): Promise<string> {
try {
const packArgs = ['pack'];
if (outputDir) {
packArgs.push('--pack-destination', outputDir);
}
const output = this.execNpmCommand(packArgs, true);
const tarballName = output.trim().split('\n').pop() || '';
return outputDir ? join(outputDir, tarballName) : tarballName;
} catch (error) {
throw new Error(`Failed to pack: ${error}`);
}
}
/**
* Execute npm command safely using execFileSync
*/
private execNpmCommand(args: string[], returnOutput = false): string {
try {
// Validate args don't contain shell metacharacters
for (const arg of args) {
if (/[;&|`$()<>]/.test(arg)) {
throw new Error(`Invalid argument: contains shell metacharacters`);
}
}
const output = execFileSync('npm', args, {
cwd: this.cwd,
encoding: 'utf-8',
shell: false,View on GitHub (pinned to fa13ee4ad6)
Solutions
- Create the destination first: mkdirSync(outputDir, { recursive: true }) before calling pack()
- Verify npm is on PATH in the environment that constructs the Publisher (execSync('npm --version'))
- Pass a simple absolute outputDir containing only metacharacter-free characters (no () & | < > ` $ ;)
Example fix
// before
const tarball = await publisher.pack(join(outRoot, 'dist-(1)')); // fails
// after
mkdirSync(join(outRoot, 'dist-1'), { recursive: true });
const tarball = await publisher.pack(join(outRoot, 'dist-1')); Defensive patterns
Strategy: try-catch
Validate before calling
import { mkdirSync, existsSync } from 'node:fs';
import { execSync } from 'node:child_process';
if (outputDir) mkdirSync(outputDir, { recursive: true });
execSync('npm --version'); // fail fast if npm is missing
await publisher.pack(outputDir); Try / catch
try {
const tarball = await publisher.pack(outDir);
if (!existsSync(tarball)) throw new Error(`pack reported ${tarball} but file is missing`);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
if (msg.startsWith('Failed to pack:')) {
// inspect the wrapped cause: ENOENT dir, npm missing, metacharacter guard
}
throw e;
} Prevention
- Pre-create the --pack-destination directory; npm will not create it
- Keep outputDir free of () & | < > ` $ ; characters to pass the internal guard
When it happens
Trigger: pack('/tmp/out') when /tmp/out does not exist (npm rejects --pack-destination pointing at a missing directory); npm not installed or not on PATH in the runtime container; cwd without a package.json; an argument rejected by the shell-metacharacter guard inside execNpmCommand (e.g. a destination containing parentheses).
Common situations: Minimal CI images without node/npm on PATH; passing a relative outputDir that resolves against an unexpected cwd; Windows-style paths with parentheses tripping the metacharacter check.
Related errors
- Failed to import OpenAI
- module loaded but is missing expected OAuth exports
- ruflo auth needs the '@claude-flow/security' package, which
- statusline-generator: could not locate .claude/helpers/statu
- ${result.stderr?.toString() || 'Installation failed'}
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/07866f16f85b03a4.
Report an issue: GitHub.