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

  1. Point --image at a specific image file, not a directory.
  2. Resolve symlinks and ensure the target is a regular file.
  3. Remove accidental sockets/fifos from the asset path.
  4. 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

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


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/ba5480232b6cf7fa. Report an issue: GitHub.