{"record":{"id":"07866f16f85b03a4","repo":"ruvnet/ruflo","slug":"failed-to-pack-error","errorCode":null,"errorMessage":"Failed to pack: ${error}","messagePattern":"Failed to pack: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/deployment/src/publisher.ts","lineNumber":189,"sourceCode":"    }\n  }\n\n  /**\n   * Pack package to tarball\n   */\n  async pack(outputDir?: string): Promise<string> {\n    try {\n      const packArgs = ['pack'];\n      if (outputDir) {\n        packArgs.push('--pack-destination', outputDir);\n      }\n\n      const output = this.execNpmCommand(packArgs, true);\n      const tarballName = output.trim().split('\\n').pop() || '';\n\n      return outputDir ? join(outputDir, tarballName) : tarballName;\n    } catch (error) {\n      throw new Error(`Failed to pack: ${error}`);\n    }\n  }\n\n  /**\n   * Execute npm command safely using execFileSync\n   */\n  private execNpmCommand(args: string[], returnOutput = false): string {\n    try {\n      // Validate args don't contain shell metacharacters\n      for (const arg of args) {\n        if (/[;&|`$()<>]/.test(arg)) {\n          throw new Error(`Invalid argument: contains shell metacharacters`);\n        }\n      }\n      const output = execFileSync('npm', args, {\n        cwd: this.cwd,\n        encoding: 'utf-8',\n        shell: false,","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/deployment/src/publisher.ts#L171-L207","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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 () & | < > ` $ ;)"],"exampleFix":"// before\nconst tarball = await publisher.pack(join(outRoot, 'dist-(1)')); // fails\n\n// after\nmkdirSync(join(outRoot, 'dist-1'), { recursive: true });\nconst tarball = await publisher.pack(join(outRoot, 'dist-1'));","handlingStrategy":"try-catch","validationCode":"import { mkdirSync, existsSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nif (outputDir) mkdirSync(outputDir, { recursive: true });\nexecSync('npm --version'); // fail fast if npm is missing\nawait publisher.pack(outputDir);","typeGuard":null,"tryCatchPattern":"try {\n  const tarball = await publisher.pack(outDir);\n  if (!existsSync(tarball)) throw new Error(`pack reported ${tarball} but file is missing`);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (msg.startsWith('Failed to pack:')) {\n    // inspect the wrapped cause: ENOENT dir, npm missing, metacharacter guard\n  }\n  throw e;\n}","preventionTips":["Pre-create the --pack-destination directory; npm will not create it","Keep outputDir free of () & | < > ` $ ; characters to pass the internal guard"],"tags":["npm","pack","tarball","child-process"],"backgroundTag":"npm-pack-failed","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}