{"record":{"id":"c9c16831f07c797e","repo":"jackwener/OpenCLI","slug":"path-resolve-coverpath-c9c168","errorCode":null,"errorMessage":"封面文件不存在: ${path.resolve(coverPath)}","messagePattern":"封面文件不存在: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/douyin/publish.js","lineNumber":136,"sourceCode":"        if (!['.mp4', '.mov', '.avi', '.webm'].includes(ext)) {\n            throw new ArgumentError(`不支持的视频格式: ${ext}（支持 mp4/mov/avi/webm）`);\n        }\n        const fileSize = fs.statSync(videoPath).size;\n        const title = kwargs.title;\n        if (title.length > 30) {\n            throw new ArgumentError('标题不能超过 30 字');\n        }\n        const caption = kwargs.caption || '';\n        if (caption.length > 1000) {\n            throw new ArgumentError('正文不能超过 1000 字');\n        }\n        const timingTs = toUnixSeconds(kwargs.schedule);\n        validateTiming(timingTs);\n        const visibilityType = VISIBILITY_MAP[kwargs.visibility] ?? 0;\n        const coverPath = kwargs.cover;\n        if (coverPath) {\n            if (!fs.existsSync(path.resolve(coverPath))) {\n                throw new ArgumentError(`封面文件不存在: ${path.resolve(coverPath)}`);\n            }\n        }\n        // ── Phase 1: upload credentials ────────────────────────────────────\n        const credentials = await getUploadAuthV5Credentials(page);\n        // ── Phase 2: Apply TOS upload URL ───────────────────────────────────\n        const tosUploadInfo = await applyVideoUploadInner(fileSize, credentials);\n        let coverUri = '';\n        let coverWidth = 720;\n        let coverHeight = 1280;\n        // ── Phase 3: TOS upload ─────────────────────────────────────────────\n        await tosUpload({\n            filePath: videoPath,\n            uploadInfo: tosUploadInfo,\n            credentials,\n            onProgress: (uploaded, total) => {\n                const pct = Math.round((uploaded / total) * 100);\n                process.stderr.write(`\\r  上传进度: ${pct}%`);\n            },","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/publish.js#L118-L154","documentation":"When a cover image path (--cover) is supplied, publish.js checks existence synchronously with fs.existsSync(path.resolve(coverPath)) before uploading. If the resolved path does not exist on disk, it throws this ArgumentError immediately. The error includes the resolved absolute path to make the mismatch obvious.","triggerScenarios":"Passing kwargs.cover pointing to a file that does not exist at publish time — wrong relative path (resolved against CWD), file deleted/moved after typing the command, or a typo in the filename/extension.","commonSituations":"Running the CLI from a different working directory than expected so a relative cover path resolves elsewhere; cover generated by a previous step that failed; shell quoting stripping characters from the path; macOS vs Linux case-sensitive filesystems.","solutions":["Verify the file exists: run ls on the exact path passed to --cover","Pass an absolute path (path.resolve) or run the CLI from the directory containing the cover","Fix typos in the filename/extension and confirm case matches on case-sensitive filesystems","Regenerate or re-export the cover image if a prior pipeline step failed to produce it"],"exampleFix":"// before\nawait douyin.publish({ cover: './cover.png' }); // run from wrong CWD\n// after\nimport fs from 'fs';\nimport path from 'path';\nconst cover = path.resolve('./cover.png');\nif (!fs.existsSync(cover)) throw new Error(`cover missing: ${cover}`);\nawait douyin.publish({ cover });","handlingStrategy":"validation","validationCode":"import fs from 'fs';\nimport path from 'path';\nconst resolvedCover = path.resolve(kwargs.cover);\nif (!fs.existsSync(resolvedCover) || !fs.statSync(resolvedCover).isFile()) {\n  throw new Error(`cover file missing: ${resolvedCover}`);\n}","typeGuard":"function coverFileExists(p) {\n  try { return fs.existsSync(p) && fs.statSync(p).isFile(); } catch { return false; }\n}","tryCatchPattern":"try {\n  await douyin.publish({ cover });\n} catch (e) {\n  if (e instanceof ArgumentError && /封面文件不存在/.test(e.message)) {\n    console.error(`Fix --cover path; resolved to: ${e.message}`);\n  } else throw e;\n}","preventionTips":["Always pass absolute paths for asset files","Check cwd assumptions in scripts that build relative paths","Verify generated cover files exist before chaining pipeline steps","Watch for case-sensitivity when moving between macOS and Linux"],"tags":["validation","filesystem","argument-error"],"backgroundTag":"file-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}