jackwener/OpenCLI · error · CliError

FILE_NOT_FOUND

FILE_NOT_FOUND

Error message

FILE_NOT_FOUND

What it means

FILE_NOT_FOUND is thrown by resolveImageInput when an image input is neither a URL (http/https/data:) nor an existing file on disk. resolveImageInput resolves the path and checks fs.existsSync before reading; any command accepting an --image input goes through this guard.

Source

Thrown at clis/yollomi/utils.js:81

                    : 'Check the model and parameters');
    }
    try {
        return JSON.parse(result.body);
    }
    catch {
        throw new CliError('API_ERROR', 'Invalid JSON response', 'Try again');
    }
}
/**
 * Resolve an image input: local file → base64 data URL, URL → as-is.
 */
export function resolveImageInput(input) {
    if (input.startsWith('http://') || input.startsWith('https://') || input.startsWith('data:')) {
        return input;
    }
    const resolved = path.resolve(input);
    if (!fs.existsSync(resolved)) {
        throw new CliError('FILE_NOT_FOUND', `File not found: ${resolved}`, 'Provide a valid file path or URL');
    }
    const ext = path.extname(resolved).toLowerCase();
    const mimeMap = {
        '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
        '.png': 'image/png', '.gif': 'image/gif',
        '.webp': 'image/webp', '.bmp': 'image/bmp',
    };
    const mime = mimeMap[ext] || 'image/png';
    const data = fs.readFileSync(resolved);
    return `data:${mime};base64,${data.toString('base64')}`;
}
export async function downloadOutput(url, outputDir, filename) {
    fs.mkdirSync(outputDir, { recursive: true });
    const destPath = path.join(outputDir, filename);
    const resp = await fetch(url);
    if (!resp.ok)
        throw new CliError('DOWNLOAD_ERROR', `Download failed: HTTP ${resp.status}`, 'URL may have expired');
    const buffer = Buffer.from(await resp.arrayBuffer());

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the path with `ls <path>` and correct typos
  2. Use an absolute path or run the command from the directory containing the file
  3. Alternatively pass an http(s) or data: URL instead of a local file
  4. If the file was moved/generated elsewhere, regenerate or copy it before running

Example fix

// before
yollomi upscale --image ./imges/photo.png   # typo
// FILE_NOT_FOUND
// after
yollomi upscale --image /home/me/images/photo.png
Defensive patterns

Strategy: validation

Validate before calling

const resolved = path.resolve(input);
if (!input.startsWith('http') && !input.startsWith('data:') && !fs.existsSync(resolved)) {
  throw new Error(`Input image does not exist: ${resolved}`);
}

Type guard

function isExistingPathOrUrl(input) {
  return /^(https?:\/\/|data:)/.test(input) || fs.existsSync(path.resolve(input));
}

Try / catch

try {
  await upscale(page, { image: input });
} catch (e) {
  if (e.code === 'FILE_NOT_FOUND') console.error(`Bad path: ${e.message} — use an absolute path or URL`);
  else throw e;
}

Prevention

When it happens

Trigger: Passing --image with a relative or absolute path that does not exist after path.resolve — e.g. a typo, a file deleted/moved after typing the command, or running from a different working directory than assumed.

Common situations: Running the CLI from a different cwd so relative paths break, typos in the filename, referencing files in another session's temp directory, or confusing an image URL with a local path (the guard accepts URLs, so this only fires for bad local paths).

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/63252db605eebeef. Report an issue: GitHub.