{"record":{"id":"2a568bef0a2290ff","repo":"jackwener/OpenCLI","slug":"not-a-valid-image-file-abspath","errorCode":null,"errorMessage":"Not a valid image file: ${absPath}","messagePattern":"Not a valid image file: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xianyu/publish.js","lineNumber":72,"sourceCode":"    return condition;\n}\n\nfunction validateImagePaths(raw) {\n    if (!raw) return [];\n    const paths = String(raw).split(',').map((item) => item.trim()).filter(Boolean);\n    if (paths.length === 0) return [];\n    if (paths.length > MAX_IMAGES) {\n        throw new ArgumentError(`xianyu publish images supports at most ${MAX_IMAGES} files`);\n    }\n    return paths.map((item) => {\n        const absPath = path.resolve(item);\n        const ext = path.extname(absPath).toLowerCase();\n        if (!SUPPORTED_IMAGE_EXTENSIONS.has(ext)) {\n            throw new ArgumentError(`Unsupported image format \"${ext}\". Supported: jpg, jpeg, png, webp`);\n        }\n        const stat = fs.statSync(absPath, { throwIfNoEntry: false });\n        if (!stat || !stat.isFile()) {\n            throw new ArgumentError(`Not a valid image file: ${absPath}`);\n        }\n        return absPath;\n    });\n}\n\nfunction normalizePublishArgs(kwargs) {\n    const price = parsePositivePrice(kwargs.price, 'price');\n    if (price == null) {\n        throw new ArgumentError('xianyu publish price cannot be empty');\n    }\n    const normalized = {};\n    normalized.title = requireText(kwargs.title, 'title');\n    normalized.description = requireText(kwargs.description, 'description');\n    normalized.price = price;\n    normalized.condition = validateCondition(kwargs.condition);\n    normalized.category = requireText(kwargs.category, 'category');\n    normalized.original_price = parsePositivePrice(kwargs.original_price, 'original_price');\n    normalized.location = kwargs.location ? requireText(kwargs.location, 'location') : '';","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xianyu/publish.js#L54-L90","documentation":"validateImagePaths throws ArgumentError when a path with a supported extension does not resolve to an existing regular file. fs.statSync(absPath, { throwIfNoEntry: false }) returns undefined for missing paths, and directories also fail the stat.isFile() check.","triggerScenarios":"Passing an images list where any entry resolves (via path.resolve) to a nonexistent path, deleted file, or directory, e.g. images: '/tmp/photos,/tmp/missing.jpg'.","commonSituations":"Relative paths resolved against an unexpected cwd, files deleted between listing and publish, typos in file names, empty comma entries producing odd paths, or passing a directory instead of files.","solutions":["fs.statSync each path and require isFile() before calling publish","Use absolute paths or ensure the process cwd matches where relative paths are defined","Confirm file names/spelling in the directory; correct or remove the bad entry"],"exampleFix":"// before\nawait publish({ images: './photos/product.jpg,./photos' }); // directory passed\n// after\nconst images = ['./photos/product.jpg'].filter((p) => fs.statSync(p).isFile());\nawait publish({ images: images.join(',') });","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nconst path = require('path');\nconst checked = String(images).split(',').map((p) => path.resolve(p.trim())).filter(Boolean);\nfor (const p of checked) {\n  const st = fs.statSync(p, { throwIfNoEntry: false });\n  if (!st || !st.isFile()) throw new Error(`Not a valid image file: ${p}`);\n}","typeGuard":"function isExistingFile(p) {\n  const st = fs.statSync(path.resolve(p), { throwIfNoEntry: false });\n  return Boolean(st && st.isFile());\n}","tryCatchPattern":"try {\n  await publish({ images });\n} catch (e) {\n  if (e instanceof ArgumentError && /Not a valid image file/.test(e.message)) {\n    const bad = e.message.split(': ')[1];\n    console.error(`Missing or not a file: ${bad}; check cwd and spelling`);\n  } else throw e;\n}","preventionTips":["Stat every path with isFile() before calling publish","Use absolute paths (path.resolve) to avoid cwd surprises","Filter out empty entries from comma-separated lists"],"tags":["validation","argument-error","filesystem","images"],"backgroundTag":"file-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}