{"record":{"id":"d3571e81bb38eb9e","repo":"paperclipai/paperclip","slug":"acpx-module-must-be-a-bounded-regular-file","errorCode":null,"errorMessage":"ACPX module must be a bounded regular file","messagePattern":"ACPX module must be a bounded regular file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/acpx/private-snapshot.ts","lineNumber":120,"sourceCode":"      const canonical = await realpath(source);\n      const mapped = mapPath(canonical);\n      // Package-manager links to unqualified packages do not grant import authority.\n      if (mapped) await symlink(mapped, target);\n      return;\n    }\n    if (!within(root, await realpath(source)))\n      throw new Error(\"ACPX snapshot escaped its package\");\n    if (before.isDirectory()) {\n      await mkdir(target, { mode: 0o700 });\n      directories.push(target);\n      for (const entry of await readdir(source))\n        await copy(join(source, entry), join(target, entry), root);\n      if (!same(before, await lstat(source, { bigint: true })))\n        throw new Error(\"ACPX package directory changed during snapshot\");\n      return;\n    }\n    if (!before.isFile() || before.size > 16n * 1024n * 1024n)\n      throw new Error(\"ACPX module must be a bounded regular file\");\n    bytesCopied += Number(before.size);\n    if (bytesCopied > MAX_PACKAGE_SNAPSHOT_BYTES)\n      throw new Error(\"ACPX package snapshot exceeds its byte bound\");\n    const handle = await open(\n      source,\n      constants.O_RDONLY | constants.O_NOFOLLOW,\n    );\n    try {\n      if (!same(before, await handle.stat({ bigint: true })))\n        throw new Error(\"ACPX module changed before snapshot\");\n      const bytes = await readSnapshotBytes(handle, Number(before.size));\n      if (\n        !same(before, await handle.stat({ bigint: true })) ||\n        !same(before, await lstat(source, { bigint: true }))\n      ) {\n        throw new Error(\"ACPX module changed during snapshot\");\n      }\n      await writeFile(target, bytes, { flag: \"wx\", mode: 0o400 });","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/acpx/private-snapshot.ts#L102-L138","documentation":"For every non-directory entry, copy() requires it to be a regular file no larger than 16 MiB; otherwise it throws 'ACPX module must be a bounded regular file'. This rejects special files (devices, sockets, FIFOs) and oversized modules, keeping each snapshot module bounded and safely bufferable in memory.","triggerScenarios":"copy() walks into an entry that lstat reports as not a regular file (symlink handled earlier; so FIFOs, sockets, device nodes, or directories-as-symlink leftovers) OR a regular file whose size exceeds 16n*1024n*1024n bytes.","commonSituations":"A package containing large bundled assets (models, wasm blobs, media) over 16 MiB; leftover Unix sockets/FIFOs in a build directory; special files created by tests inside the package tree.","solutions":["Remove or externalize files larger than 16 MiB from the package root (ship them via another mechanism)","Delete stray FIFOs/sockets/device files from the package directory","Confirm the admitted root is a source package, not a build output directory containing artifacts","If a large file is legitimately required, pre-process/split it below the 16 MiB bound"],"exampleFix":"// before: 40MB model shipped inside package\npackages/my-app/assets/model.bin\n// after: keep it out of the snapshot root\nmove model.bin to external storage and reference by URL","handlingStrategy":"validation","validationCode":"for (const f of await walk(root)) {\n  const st = await fs.lstat(f);\n  if (!st.isFile()) throw new Error(`special file in package: ${f}`);\n  if (st.size > 16 * 1024 * 1024) throw new Error(`file >16MiB: ${f}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await createAcpxPrivateSnapshot({ roots: [root] });\n} catch (e) {\n  if (e.message.includes('bounded regular file')) {\n    throw new Error(`Package ${root} contains a special or >16MiB file; clean it before snapshot`);\n  }\n  throw e;\n}","preventionTips":["Keep large assets out of admitted package roots","Delete stray FIFOs/sockets left by tests before snapshotting","Pre-flight scan package roots with lstat for non-regular and oversized files"],"tags":["filesystem","limit","file-type","snapshot"],"backgroundTag":"incompatible-source-type","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}