jackwener/OpenCLI · error · ArgumentError
File must be a readable text file: ${path}
Error message
File must be a readable text file: ${path} What it means
After stat() succeeds, readUtf8File checks fileStat.isFile() to ensure the target is a regular file, not a directory, FIFO, socket, or device. If it is not a regular file it throws ArgumentError 'File must be a readable text file: <path>'.
Source
Thrown at clis/_atlassian/shared.js:301
return n;
}
export function requireExecute(args, commandName) {
if (args.execute !== true) {
throw new ArgumentError(`${commandName} requires --execute to perform a remote write`);
}
}
export async function readUtf8File(filePath) {
const path = requireString(filePath, '--file');
let fileStat;
try {
fileStat = await stat(path);
} catch {
throw new ArgumentError(`File not found: ${path}`);
}
if (!fileStat.isFile()) {
throw new ArgumentError(`File must be a readable text file: ${path}`);
}
let raw;
try {
raw = await readFile(path);
} catch {
throw new ArgumentError(`File could not be read: ${path}`);
}
try {
return new TextDecoder('utf-8', { fatal: true }).decode(raw);
} catch {
throw new ArgumentError(`File could not be decoded as UTF-8 text: ${path}`);
}
}
export function htmlEscape(value) {
return String(value ?? '')
.replace(/&/g, '&')
.replace(/</g, '<')View on GitHub (pinned to 49907e53dc)
Solutions
- Pass the path to a regular file, not a directory or special file.
- Check the target with `file <path>` or `stat -c %F <path>` to confirm it is a regular file.
- If you meant to send several files, iterate over the directory and pass each file individually.
Example fix
// before cli confluence create --file ./pages/ // after cli confluence create --file ./pages/index.md
Defensive patterns
Strategy: validation
Validate before calling
const s = await stat(p);
if (!s.isFile()) throw new Error(`--file must be a regular file, got: ${p}`); Type guard
const isRegularFile = async (p) => { try { return (await stat(p)).isFile(); } catch { return false; } }; Try / catch
try {
const text = await readUtf8File(p);
} catch (err) {
if (err.name === 'ArgumentError' && err.message.includes('readable text file')) {
console.error(`${p} is not a regular file; pass a file, not a directory or device.`);
}
throw err;
} Prevention
- Verify with `file <path>` / stat that targets are regular files.
- Expand globs to concrete files before passing them.
- Never point --file at directories; loop over entries instead.
When it happens
Trigger: Passing a directory path (e.g. --file ./docs) or a special file (named pipe, /dev/ node) to readUtf8File.
Common situations: Pointing --file at a folder instead of a file by mistake; shell glob or variable expansion resolving to a directory; passing a device or procfs path expecting it to behave like a text file.
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
- File not found: ${path}
- ${label}路径不是文件: ${resolved}
- <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/c5b543f69196ca3e.
Report an issue: GitHub.