jackwener/OpenCLI · error · ArgumentError

File could not be read: ${path}

Error message

File could not be read: ${path}

What it means

If the file exists and is a regular file but readFile() still rejects (permission denied, I/O error, race with deletion), readUtf8File throws ArgumentError 'File could not be read: <path>'. It normalizes low-level fs failures into a single user-facing message.

Source

Thrown at clis/_atlassian/shared.js:307

    }
}

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, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;');
}

export function htmlToMarkdown(html) {
    return coreHtmlToMarkdown(String(html ?? ''));

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Fix read permissions: chmod/chown or run as a user with access, then retry.
  2. Confirm the file still exists at read time (was not removed by another process).
  3. Verify volume mounts / network storage availability if running in a container or on a remote FS.

Example fix

// before
-rw-------  1 root root  512 notes.md   # run as non-root
// after
chmod 644 notes.md   # or run the CLI as the file owner
Defensive patterns

Strategy: validation

Validate before calling

const s = await stat(p);
await access(p, fsConstants.R_OK); // throws EACCES early if unreadable

Type guard

const isReadableFile = async (p) => { try { await access(p, fsConstants.R_OK); 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('could not be read')) {
    console.error(`Cannot read ${p}: check permissions and that the file still exists.`);
  }
  throw err;
}

Prevention

When it happens

Trigger: stat() succeeds but readFile() rejects: no read permission, file deleted between stat and read, I/O error, or path is a symlink to an unreadable target.

Common situations: File owned by another user / chmod 600 while running under a service account; NFS or network mount hiccup; TOCTOU deletion in scripts; running in a container without the file mounted.

Related errors


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