nexu-io/open-design · error · Error
--image is not a regular file: ${rel}
Error message
--image is not a regular file: ${rel} What it means
Thrown by resolveProjectImage when fs.stat succeeds but the entry is not a regular file (info.isFile() is false). The image pipeline can only stream regular file bytes; directories, symbolic links to directories, device/socket/pipe entries are rejected.
Source
Thrown at apps/daemon/src/media/index.ts:237
if (typeof rel !== 'string' || !rel.trim()) return null;
const projectRootResolved = path.resolve(projectDir);
const abs = path.resolve(projectRootResolved, rel.trim());
if (
abs !== projectRootResolved &&
!abs.startsWith(projectRootResolved + path.sep)
) {
throw new Error(
`--image path "${rel}" resolves outside the project directory.`,
);
}
let info;
try {
info = await stat(abs);
} catch {
throw new Error(`--image not found: ${rel}`);
}
if (!info.isFile()) {
throw new Error(`--image is not a regular file: ${rel}`);
}
// Cap at 16 MB. Beyond this, base64 inflation alone (≈4/3) starts
// hitting body-size limits at the upstream APIs and our own express
// 4mb body cap on inbound requests; bigger payloads should travel
// via the dedicated upload endpoint, not the dispatcher.
const MAX_IMAGE_BYTES = 16 * 1024 * 1024;
if (info.size > MAX_IMAGE_BYTES) {
throw new Error(
`--image too large (${info.size} bytes; max ${MAX_IMAGE_BYTES}).`,
);
}
const bytes = await readFile(abs);
const ext = path.extname(abs).toLowerCase();
// Tight allowlist: only what i2v / image-edit endpoints actually
// consume. Avoids smuggling arbitrary content through as data URLs.
const mime = ({
'.png': 'image/png',
'.jpg': 'image/jpeg',View on GitHub (pinned to 5be4028344)
Solutions
- Point --image at a specific image file, not a directory.
- Resolve symlinks and ensure the target is a regular file.
- Remove accidental sockets/fifos from the asset path.
- List the directory contents to find the actual image file.
Example fix
// before --image assets/ // after --image assets/hero.png
Defensive patterns
Strategy: validation
Validate before calling
import { stat } from 'node:fs/promises';
const info = await stat(abs);
if (!info.isFile()) throw new Error(`--image is not a regular file: ${rel}`); Type guard
async function isRegularFile(abs: string): Promise<boolean> {
try { return (await stat(abs)).isFile(); } catch { return false; }
} Prevention
- Point --image at a file, never a directory.
- Resolve symlinks to ensure they target regular files.
- Validate the asset path is a file in your UI before submit.
When it happens
Trigger: Passing `--image assets/` (a directory); a path that resolves to a FIFO/socket; a dangling or directory-targeting symlink; pointing at a special device file.
Common situations: Agent passes a folder path instead of a file; symlink to a directory; OS-created socket/fifo at the path; misconfigured asset path.
Related errors
- --image not found: ${rel}
- --image path "${rel}" resolves outside the project directory
- --image too large (${info.size} bytes; max ${MAX_IMAGE_BYTES
- --image has unsupported extension "${ext}". Use png, jpg, jp
- unsupported surface: ${surface}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/ba5480232b6cf7fa.
Report an issue: GitHub.