jackwener/OpenCLI · error · CommandExecutionError
Failed to inspect Pixiv download target ${target}: ${error?.
Error message
Failed to inspect Pixiv download target ${target}: ${error?.message || error} What it means
pixivPathEntryExists uses fs.lstatSync to test whether a download destination exists. ENOENT is treated as 'does not exist', but any other lstat failure (EACCES, ELOOP, ENOTDIR, EIO, etc.) is unrecoverable for the safety check, so a CommandExecutionError wrapping the underlying message is thrown.
Source
Thrown at clis/pixiv/novel-download-utils.js:106
let canonicalAncestor;
try {
canonicalAncestor = fs.realpathSync.native(ancestor);
} catch {
throw new ArgumentError(`output path is not a safe directory: ${ancestor}`);
}
if (!fs.statSync(canonicalAncestor).isDirectory()) {
throw new ArgumentError(`output path is not a safe directory: ${ancestor}`);
}
return path.join(canonicalAncestor, ...missingParts);
}
export function pixivPathEntryExists(target) {
try {
fs.lstatSync(target);
return true;
} catch (error) {
if (error?.code === 'ENOENT') return false;
throw new CommandExecutionError(`Failed to inspect Pixiv download target ${target}: ${error?.message || error}`);
}
}
export async function fetchNovelForDownload(page, id) {
const body = await pixivFetch(page, `/ajax/novel/${id}`, {
notFoundMsg: `Novel not found: ${id}`,
});
return requireNovelDownloadBody(body, id);
}
export function formatNovelContent(body, format) {
const tags = tagsToString(body.tags);
const url = `https://www.pixiv.net/novel/show.php?id=${body.id}`;
if (format === 'md') {
return [
`# ${body.title}`,
'',
`- Author: ${body.userName}`,View on GitHub (pinned to 49907e53dc)
Solutions
- Fix permissions on the destination's parent directories (chmod/chown for the running user).
- Remove symlink loops or dead links in the path (find -type l -xtype l).
- Ensure every component of the output path except the final entry is a directory.
- Reconnect/remount the storage volume and retry; if transient, wrap the call in retry with backoff.
Example fix
// before -o /mnt/usb/novels // usb unmounted -> EIO on lstat // after (shell) $ mount /mnt/usb && pixiv-novel download 12345 -o /mnt/usb/novels
Defensive patterns
Strategy: retry
Validate before calling
import fs from 'node:fs';
function canProbe(p) {
try { fs.lstatSync(p); return true; }
catch (e) { return e.code === 'ENOENT'; }
} Try / catch
try {
await downloadNovel(id, { output });
} catch (e) {
if (e.message.startsWith('Failed to inspect Pixiv download target')) {
console.error(`Fix filesystem access for output path: ${e.message}`);
// remount/chmod, then retry once
} else throw e;
} Prevention
- Keep output directories owned by and writable to the running user.
- Avoid symlink loops in destination paths.
- Verify network/USB volumes are mounted before batch runs.
- Keep every path component above the destination a real directory.
When it happens
Trigger: prepareIllustPlan, commitIllustPlan, or prepareNovelFile probes a destination path whose parent directory denies permission, contains a symlink loop, has a non-directory component, or the path is on a failing volume.
Common situations: Output directory made read-only or owned by another user; destination path contains a dead symlink; output path passes through a file (ENOTDIR); disk/USB/network drive dropped offline mid-session.
Related errors
- output path is not a safe directory: ${ancestor}
- File could not be read: ${path}
- Receipt file cannot be read: ${receipt}
- Could not store Midjourney ${kind} at ${filePath}: ${errorMe
- Could not read Midjourney usage snapshots: ${errorMessage(er
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/e165570d0eae4eff.
Report an issue: GitHub.