{"record":{"id":"7bcae8e663cc1fb0","repo":"ruvnet/ruflo","slug":"expand-archive-failed-exit-result-exitcode","errorCode":null,"errorMessage":"Expand-Archive failed (exit ${result.exitCode}): ${result.stderr || result.stdout}","messagePattern":"Expand-Archive failed \\(exit (.+?)\\): (.+?)","errorType":"exception","errorClass":"ExtractionError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/proxy/install.ts","lineNumber":53,"sourceCode":"  if (result.exitCode !== 0) {\n    throw new ExtractionError(`tar extraction failed (exit ${result.exitCode}): ${result.stderr || result.stdout}`);\n  }\n}\n\n/**\n * Single-quoted literal paths (doubling any embedded single quote per\n * PowerShell string-literal escaping) passed as ONE argv element to\n * `-Command`. shell:false means no OS shell ever tokenizes this string —\n * only powershell.exe's own parser does.\n */\nasync function extractWithPowerShell(archivePath: string, extractDir: string): Promise<void> {\n  const { SafeExecutor } = await import('@claude-flow/security');\n  const escape = (p: string) => p.replace(/'/g, \"''\");\n  const command = `Expand-Archive -LiteralPath '${escape(archivePath)}' -DestinationPath '${escape(extractDir)}' -Force`;\n  const exec = new SafeExecutor({ allowedCommands: ['powershell', 'powershell.exe'], timeout: 60_000 });\n  const result = await exec.execute('powershell', ['-NoProfile', '-NonInteractive', '-Command', command]);\n  if (result.exitCode !== 0) {\n    throw new ExtractionError(`Expand-Archive failed (exit ${result.exitCode}): ${result.stderr || result.stdout}`);\n  }\n}\n\n/**\n * Extracts the archive via the OS's own tools — `tar` for `.tar.gz`\n * (present on macOS/Linux/Windows 10+), PowerShell `Expand-Archive`\n * specifically for `.zip` on Windows. Zero new archive-parsing dependency,\n * matching this repo's existing taste for shelling out over adding a parser dep.\n *\n * `Expand-Archive` stays the PRIMARY `.zip` path — bsdtar's zip support is\n * still not something to lean on by default. But `Microsoft.PowerShell.Archive`\n * is a *script* module resolved through PowerShell's module autoloading, so it\n * can fail for environment reasons entirely unrelated to the archive. Observed\n * in the wild on a healthy Windows 11 box, from ruflo's own `-NonInteractive`\n * child process:\n *\n *   Expand-Archive : The 'Expand-Archive' command was found in the module\n *   'Microsoft.PowerShell.Archive', but the module could not be loaded.","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/ruvnet/ruflo/blob/29f048fc3b556f857cf2b126d2a84c19d2daa0d0/v3/@claude-flow/cli/src/proxy/install.ts#L35-L71","documentation":"On Windows, .zip extraction uses PowerShell's Expand-Archive via SafeExecutor (allowlist powershell/powershell.exe, 60s timeout, paths single-quote-escaped). A non-zero exit throws ExtractionError with the code and PowerShell's stderr. Expand-Archive is a script module (Microsoft.PowerShell.Archive) resolved through module autoloading, so it fails when PowerShell's execution policy blocks scripts, the module is missing/damaged, or powershell.exe isn't reachable. In the normal flow this error is caught and bsdtar 'xf' is tried as fallback — you see this message alone only when extraction is invoked directly or you're tracing the primary failure embedded in the both-extractors error.","triggerScenarios":"powershell -NoProfile -NonInteractive -Command \"Expand-Archive ...\" exits non-zero: ExecutionPolicy Restricted blocking the Archive script module, PSModulePath broken so Microsoft.PowerShell.Archive can't autoload, PowerShell 7-only hosts where powershell.exe (5.1) is stripped, corrupted zip, or disk-full/locked destination.","commonSituations":"Hardened Windows images with Restricted execution policy; systems where PSModulePath was overwritten by other tooling; enterprises removing Windows PowerShell 5.1 in favor of pwsh (the allowlist names powershell/powershell.exe only); AV holding locks on extracted files.","solutions":["Read the embedded stderr — 'running scripts is disabled' points at execution policy.","Allow the archive module: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned, or fix PSModulePath so Microsoft.PowerShell.Archive autoloads.","Ensure the automatic fallback can work: keep Windows 10+ bsdtar (tar.exe) available — the installer already retries with `tar xf` when Expand-Archive fails, so a healthy tar makes this error invisible.","Free disk/AV locks on the extract directory, then re-run install."],"exampleFix":"# before: policy blocks the script module -> exit non-zero\nPS> claude-flow install   # Expand-Archive failed ...\n\n# after\nPS> Set-ExecutionPolicy -Scope CurrentUser RemoteSigned\nPS> claude-flow install   # Expand-Archive (or tar fallback) succeeds","handlingStrategy":"fallback","validationCode":"import { execFileSync } from 'node:child_process';\nfunction expandArchiveWorks(): boolean {\n  try {\n    execFileSync('powershell', ['-NoProfile', '-NonInteractive', '-Command',\n      'Get-Command Expand-Archive | Out-Null'], { timeout: 15_000, stdio: 'ignore' });\n    return true;\n  } catch { return false; }\n}\n// On Windows, before relying on zip extraction:\nif (!expandArchiveWorks() && !tarAvailable()) throw new Error('no working zip extractor: fix execution policy or provide tar.exe');","typeGuard":"function isPowerShellExtractError(e: unknown): e is Error {\n  return e instanceof Error && e.message.startsWith('Expand-Archive failed (exit ');\n}","tryCatchPattern":"try {\n  await extractZip(archivePath, dir); // primary: Expand-Archive\n} catch (primary) {\n  if (!isPowerShellExtractError(primary)) throw primary;\n  try {\n    await extractWithTar(archivePath, dir, 'xf'); // fallback: bsdtar sniffs zip format\n  } catch (fallback) {\n    throw new Error(`zip extraction exhausted: Expand-Archive: ${primary.message} — tar: ${fallback.message}`);\n  }\n}","preventionTips":["Keep at least one extractor healthy on Windows: fix execution policy (RemoteSigned for CurrentUser) or guarantee tar.exe (Windows 10 1803+).","Include Expand-Archive availability in your environment preflight on Windows images.","Don't strip powershell.exe from images if you rely on .zip proxy installs — the allowlist names powershell/powershell.exe only."],"tags":["proxy","install","windows","powershell","extraction"],"backgroundTag":"archive-extraction-failed","analyzedSha":"29f048fc3b556f857cf2b126d2a84c19d2daa0d0","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}