{"record":{"id":"548dfa3d660efb5e","repo":"ruvnet/ruflo","slug":"release-asset-exceeds-maxbytes-byte-limit","errorCode":null,"errorMessage":"release asset exceeds ${maxBytes} byte limit","messagePattern":"release asset exceeds (.+?) byte limit","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/proxy/release.ts","lineNumber":67,"sourceCode":"\nexport interface ReleaseAssets {\n  archiveBytes: Buffer;\n  archiveFilename: string;\n  sumsBytes: Buffer;\n  sigBase64: string;\n}\n\nconst DEV_INSTALL_ENV = 'RUFLO_DEV_PROXY_INSTALL';\nconst RELEASE_SOURCE_ENV = 'RUFLO_PROXY_RELEASE_SOURCE';\nconst GH_REPO = 'cognitum-one/meta-proxy';\nconst PUBLIC_DIST_BASE = 'https://github.com/cognitum-one/meta-proxy-dist/releases/download';\nconst MAX_ARCHIVE_BYTES = 32 * 1024 * 1024;\n\nasync function downloadPublicAsset(url: string, maxBytes: number): Promise<Buffer> {\n  const response = await fetch(url, { redirect: 'follow', signal: AbortSignal.timeout(120_000) });\n  if (!response.ok) throw new Error(`release download failed: HTTP ${response.status} for ${url}`);\n  const declared = Number(response.headers.get('content-length') ?? 0);\n  if (declared > maxBytes) throw new Error(`release asset exceeds ${maxBytes} byte limit`);\n  const bytes = Buffer.from(await response.arrayBuffer());\n  if (bytes.length > maxBytes) throw new Error(`release asset exceeds ${maxBytes} byte limit`);\n  return bytes;\n}\n\nasync function ghExecutor() {\n  // Dynamic import, not a static one: @claude-flow/security is only an\n  // optionalDependency of this package (see auth/security-bridge.ts for the\n  // same reasoning) — a static top-level import would crash module load for\n  // any consumer that doesn't have it installed, even ones that never touch\n  // this dev-only download path.\n  const { SafeExecutor } = await import('@claude-flow/security');\n  return new SafeExecutor({ allowedCommands: ['gh'], timeout: 120_000 });\n}\n\n/**\n * Dev-only fallback: `gh release download` via SafeExecutor into `destDir`.\n * Requires the caller's environment to already have `gh` authenticated","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/proxy/release.ts#L49-L85","documentation":"downloadPublicAsset() refuses any asset whose declared Content-Length header exceeds the caller's cap (32 MiB for the archive, MAX_ARCHIVE_BYTES). This is the pre-download guard evaluated before the body is read, bounding memory use on untrusted release responses.","triggerScenarios":"A genuine meta-proxy release whose archive grew past 32 MiB (added features, static linking), or a misrouted/compromised URL serving an unexpectedly large body with a truthful Content-Length.","commonSituations":"Upstream release size creep after the installed ruflo version was cut; mirrors that pad or wrap assets; stale cached redirects landing on a bigger file.","solutions":["Update the ruflo CLI — the size cap is raised upstream when legitimate releases grow","Inspect the reported URL manually (curl -I) and compare the real Content-Length with the official release","If the official release is unexpectedly oversized, treat it as a potential supply-chain incident and report it rather than working around it"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const res = await fetch(assetUrl, { method: 'HEAD' });\nconst size = Number(res.headers.get('content-length') ?? 0);\nif (size > 32 * 1024 * 1024) {\n  console.error('archive exceeds this CLI version\\'s cap — update ruflo before installing');\n}","typeGuard":"const isSizeLimit = (e: unknown): e is Error =>\n  e instanceof Error && /exceeds \\d+ byte limit/.test(e.message);","tryCatchPattern":"try {\n  await installProxy({ version });\n} catch (e) {\n  if (isSizeLimit(e)) {\n    console.error('Update ruflo — the release exceeds this version\\'s size cap');\n    process.exit(3);\n  }\n  throw e;\n}","preventionTips":["Keep the CLI updated alongside release growth","Monitor release asset sizes in CI","Treat unexpected size spikes as suspicious — cross-check sha256 manually before escalating"],"tags":["download","size-limit","security","github-releases"],"backgroundTag":"download-size-limit-exceeded","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}