jackwener/OpenCLI · error · ArgumentError
${label}路径不是文件: ${resolved}
Error message
${label}路径不是文件: ${resolved} What it means
requireFilePath validates the video path before upload. After fs.statSync succeeds, it checks stat.isFile() and throws ArgumentError when the resolved path exists but is not a regular file — typically a directory, symlink-to-directory, socket, or device node. This guards the uploader from being handed a non-file path that would fail later inside the browser automation.
Source
Thrown at clis/wechat-channels/publish.js:73
return result.data;
}
return result;
}
async function evalPage(page, script) {
return unwrapEvaluateResult(await page.evaluate(script));
}
function requireFilePath(filePath, label, allowedExts) {
const resolved = path.resolve(String(filePath));
let stat;
try {
stat = fs.statSync(resolved);
} catch {
throw new ArgumentError(`${label}文件不存在: ${resolved}`);
}
if (!stat.isFile()) {
throw new ArgumentError(`${label}路径不是文件: ${resolved}`);
}
const ext = path.extname(resolved).toLowerCase();
if (!allowedExts.has(ext)) {
throw new ArgumentError(`不支持的${label}格式: ${ext}(支持 ${Array.from(allowedExts).join('/')})`);
}
return resolved;
}
function parseTimeoutSeconds(raw) {
const timeout = raw == null || raw === '' ? 600 : Number(raw);
if (!Number.isInteger(timeout) || timeout < 30) {
throw new ArgumentError('--timeout must be an integer >= 30 seconds');
}
return timeout;
}
function parseScheduleDate(raw) {
if (!raw) return null;View on GitHub (pinned to 49907e53dc)
Solutions
- Pass the full path to the actual video file, not its containing directory.
- Run ls -l <path> (or fs.statSync in Node) to confirm the path is a regular file.
- If using a variable/script, ensure it does not drop the filename (e.g. path.resolve(dir) instead of path.resolve(dir, name)).
Example fix
// before node publish.js --video ./exports // after node publish.js --video ./exports/final.mp4
Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs'), path = require('path');
const resolved = path.resolve(videoPath);
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isFile()) {
throw new Error(`Not a file: ${resolved}`);
} Type guard
function isExistingFile(p) {
try { return fs.statSync(p).isFile(); } catch { return false; }
} Try / catch
try {
await publish({ videoPath });
} catch (e) {
if (/路径不是文件/.test(e.message)) {
console.error(`Fix --video: ${videoPath} is a directory/special file`);
}
throw e;
} Prevention
- Always pass the full path including filename, never a directory.
- Validate with fs.statSync().isFile() in wrapper scripts before invoking the CLI.
- Avoid glob patterns in --video unless your shell expands them.
When it happens
Trigger: Calling videoPath (or requireFilePath directly) with a path that resolves to a directory (e.g. --video ./clips) or to a special file; passing a glob that a shell left unresolved; pointing at a mount point or device path.
Common situations: User passes the output directory instead of the rendered video file; automation passes a temp directory; a symlink resolves to a directory; copy-pasted path lost the filename portion.
Related errors
- File not found: ${path}
- File must be a readable text file: ${path}
- <train-no> "${trainNo}" does not look like a 12306 internal
- --from station must not be empty
- --to station must not be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c9a030bb1c4086b0.
Report an issue: GitHub.