{"record":{"id":"5ce141fa648c8b32","repo":"jackwener/OpenCLI","slug":"error-5ce141","errorCode":null,"errorMessage":"未检测到抖音草稿恢复提示","messagePattern":"未检测到抖音草稿恢复提示","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/douyin/draft.js","lineNumber":288,"sourceCode":"    };\n}\n/**\n * Wait until creator center shows the resumable-draft prompt after saving.\n */\nasync function waitForDraftResult(page, creationId) {\n    let lastState = { href: '', bodyText: '' };\n    for (let attempt = 0; attempt < 20; attempt += 1) {\n        lastState = (await page.evaluate(`() => ({\n      href: location.href,\n      bodyText: document.body?.innerText || ''\n    })`));\n        if (lastState.href.includes('/creator-micro/content/upload')\n            && /继续编辑/.test(lastState.bodyText)) {\n            return creationId;\n        }\n        await page.wait({ time: 1 });\n    }\n    throw new CommandExecutionError('未检测到抖音草稿恢复提示', `当前页面: ${lastState.href || 'unknown'}`);\n}\ncli({\n    site: 'douyin',\n    name: 'draft',\n    access: 'write',\n    description: '上传视频并保存为草稿',\n    domain: 'creator.douyin.com',\n    strategy: Strategy.COOKIE,\n    navigateBefore: false,\n    args: [\n        { name: 'video', required: true, positional: true, help: '视频文件路径' },\n        { name: 'title', required: true, help: '视频标题（≤30字）' },\n        { name: 'caption', default: '', help: '正文内容（≤1000字，支持 #话题）' },\n        { name: 'cover', default: '', help: '封面图片路径' },\n        { name: 'visibility', default: 'public', choices: ['public', 'friends', 'private'] },\n    ],\n    columns: ['status', 'draft_id'],\n    func: async (page, kwargs) => {","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/draft.js#L270-L306","documentation":"waitForDraftResult polls for up to 20 seconds after saving, waiting for the page to be on '/creator-micro/content/upload' with body text matching /继续编辑/ (the resumable-draft prompt). If that confirmation never appears it throws this CommandExecutionError with the last page URL as detail. The save click may have failed silently or the post-save UI copy changed.","triggerScenarios":"After clicking '暂存离开': a confirmation dialog blocks navigation, the draft-save request fails server-side, the page navigates elsewhere (e.g. content list instead of upload page), or the '继续编辑' copy was changed/removed by Douyin.","commonSituations":"Douyin save flow showing an extra confirm modal ('确定暂存？'); slow draft-save API leaving the page in the old state past 20s; UI update rewording the recovery prompt; account risk-control rejecting the save.","solutions":["Check the detail URL — if still on the composer, the click likely didn't take effect; retry the whole draft command","Look for and dismiss any confirmation modal after clicking save (extend dismissKnownModals targets)","Manually verify in creator center whether the draft was actually saved despite the missing prompt; if saved, only detection is broken — update the /继续编辑/ regex in clis/douyin/draft.js:283","Increase the 20s/20-attempt budget if drafts save slowly on your network"],"exampleFix":"// before\nif (lastState.href.includes('/creator-micro/content/upload')\n    && /继续编辑/.test(lastState.bodyText)) {\n// after: also accept landing on draft list\nif (/creator-micro\\/content/.test(lastState.href)\n    && /继续编辑|草稿/.test(lastState.bodyText)) {","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await opencli.douyin.draft({ video, title });\n} catch (e) {\n  if (e.message.includes('未检测到抖音草稿恢复提示')) {\n    // check creator center manually — the draft may exist; detection regex may be stale\n  }\n}","preventionTips":["Handle post-save confirmation modals before waiting for the prompt","Broaden the success check to any /creator-micro/content page with draft indicators","Extend the 20s wait if draft saves are slow in your environment"],"tags":["douyin","timeout","draft-save","browser-automation"],"backgroundTag":"page-load-timeout","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}