paperclipai/paperclip · error · Error
ACPX module must be a bounded regular file
Error message
ACPX module must be a bounded regular file
What it means
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.
Source
Thrown at packages/paperclip-runner/src/drivers/acpx/private-snapshot.ts:120
const canonical = await realpath(source);
const mapped = mapPath(canonical);
// Package-manager links to unqualified packages do not grant import authority.
if (mapped) await symlink(mapped, target);
return;
}
if (!within(root, await realpath(source)))
throw new Error("ACPX snapshot escaped its package");
if (before.isDirectory()) {
await mkdir(target, { mode: 0o700 });
directories.push(target);
for (const entry of await readdir(source))
await copy(join(source, entry), join(target, entry), root);
if (!same(before, await lstat(source, { bigint: true })))
throw new Error("ACPX package directory changed during snapshot");
return;
}
if (!before.isFile() || before.size > 16n * 1024n * 1024n)
throw new Error("ACPX module must be a bounded regular file");
bytesCopied += Number(before.size);
if (bytesCopied > MAX_PACKAGE_SNAPSHOT_BYTES)
throw new Error("ACPX package snapshot exceeds its byte bound");
const handle = await open(
source,
constants.O_RDONLY | constants.O_NOFOLLOW,
);
try {
if (!same(before, await handle.stat({ bigint: true })))
throw new Error("ACPX module changed before snapshot");
const bytes = await readSnapshotBytes(handle, Number(before.size));
if (
!same(before, await handle.stat({ bigint: true })) ||
!same(before, await lstat(source, { bigint: true }))
) {
throw new Error("ACPX module changed during snapshot");
}
await writeFile(target, bytes, { flag: "wx", mode: 0o400 });View on GitHub (pinned to 01ad858492)
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
Example fix
// before: 40MB model shipped inside package packages/my-app/assets/model.bin // after: keep it out of the snapshot root move model.bin to external storage and reference by URL
Defensive patterns
Strategy: validation
Validate before calling
for (const f of await walk(root)) {
const st = await fs.lstat(f);
if (!st.isFile()) throw new Error(`special file in package: ${f}`);
if (st.size > 16 * 1024 * 1024) throw new Error(`file >16MiB: ${f}`);
} Try / catch
try {
await createAcpxPrivateSnapshot({ roots: [root] });
} catch (e) {
if (e.message.includes('bounded regular file')) {
throw new Error(`Package ${root} contains a special or >16MiB file; clean it before snapshot`);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- ACPX package snapshot exceeds its file bound
- ACPX package snapshot exceeds its byte bound
- ACPX runtime executable must be a bounded executable file
- ACPX file ended during snapshot
- ACPX snapshot escaped its package
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/d3571e81bb38eb9e.
Report an issue: GitHub.