jackwener/OpenCLI · error · ArgumentError
Receipt file does not exist: ${receipt}
Error message
Receipt file does not exist: ${receipt} What it means
After statSync succeeds (with throwIfNoEntry:false it returns undefined instead of throwing for missing entries), parseReceiptPath checks that a file exists AND is a regular file. If the path is missing, or resolves to a directory/special file, this ArgumentError is thrown. It is the 'not there or not a file' sibling of the read-failure error.
Source
Thrown at clis/mercury/utils.js:44
const normalized = value.trim().toLowerCase();
if (['1', 'true', 'yes', 'y', 'on'].includes(normalized)) return true;
if (['0', 'false', 'no', 'n', 'off'].includes(normalized)) return false;
throw new ArgumentError(`Boolean argument ${name} must be true or false`);
}
return fallback;
}
function parseReceiptPath(kwargs) {
const receipt = path.resolve(requireString(kwargs, 'receipt'));
let stat;
try {
stat = fs.statSync(receipt, { throwIfNoEntry: false });
}
catch (error) {
throw new ArgumentError(`Receipt file cannot be read: ${receipt}`, error instanceof Error ? error.message : undefined);
}
if (!stat || !stat.isFile()) {
throw new ArgumentError(`Receipt file does not exist: ${receipt}`);
}
return receipt;
}
function parseAmount(kwargs) {
const amount = requireString(kwargs, 'amount').replace(/,/g, '');
if (!/^\d+(\.\d{1,2})?$/.test(amount) || Number(amount) <= 0) {
throw new ArgumentError(`Amount must be a positive number with up to two decimals: ${amount}`);
}
return amount;
}
function parseCurrency(kwargs) {
const currency = optionalString(kwargs, 'currency', 'CNY').toUpperCase();
if (!/^[A-Z]{3}$/.test(currency)) {
throw new ArgumentError(`Currency must be a three-letter ISO currency code: ${currency}`);
}
return currency;View on GitHub (pinned to 49907e53dc)
Solutions
- Run ls -l on the path and confirm a regular file exists at that exact location.
- Correct typos in the path/filename, or re-download/export the receipt file.
- If you passed a directory, point at the specific receipt file inside it.
- Add a pre-check in calling scripts: test -f "$RECEIPT" before invoking the command.
Example fix
// before --receipt ./receipts # directory // after --receipt ./receipts/receipt-2026-08-01.pdf
Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
function receiptFileExists(p) {
const st = fs.statSync(p, { throwIfNoEntry: false });
return !!st && st.isFile();
} Type guard
function isExistingFile(p) {
try { return fs.statSync(p).isFile(); } catch { return false; }
} Try / catch
try {
await reimburse({ receipt });
} catch (e) {
if (e instanceof ArgumentError && e.message.startsWith('Receipt file does not exist')) {
const dir = path.dirname(e.message.split(': ')[1] ?? receipt);
console.error(`Receipt missing. Nearby files: ${fs.readdirSync(dir).join(', ')}`);
} else throw e;
} Prevention
- Use shell completion or ls to confirm the exact filename before running
- Check --receipt points to a file, not a directory
- Regenerate/export the receipt if it was moved or cleaned up
- Wrap scripts with [[ -f $RECEIPT ]] || exit 1 guards
When it happens
Trigger: receipt path does not exist; receipt points to a directory; receipt is a fifo/socket/device node; receipt is a dangling symlink (stat returns undefined).
Common situations: Typo in filename or extension (.pdf vs .PNG); file deleted or moved after being referenced in a script; passing a directory instead of the file; shell glob that expanded to nothing.
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}
- 视频文件不存在: ${videoPath}
- Video file not found: ${resolved}
- Receipt file cannot be read: ${receipt}
- ${label} file does not exist: ${ref.value}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/62249b2cc16bedd1.
Report an issue: GitHub.