jackwener/OpenCLI · error · CommandExecutionError
填写抖音草稿表单失败: caption-editor-missing
Error message
填写抖音草稿表单失败: caption-editor-missing
What it means
When a caption is provided, fillDraftComposer locates a '[contenteditable="true"]' element to insert the caption text via document.execCommand('insertText'). If no contenteditable editor exists on the composer page it throws this CommandExecutionError with reason 'caption-editor-missing'.
Source
Thrown at clis/douyin/draft.js:107
}
return true;
}`));
if (!titleOk) {
throw new CommandExecutionError('填写抖音草稿表单失败: title-input-missing');
}
if (options.caption) {
const captionOk = (await page.evaluate(`() => {
const editor = document.querySelector('[contenteditable="true"]');
if (!(editor instanceof HTMLElement)) return false;
editor.focus();
editor.textContent = '';
document.execCommand('selectAll', false);
document.execCommand('insertText', false, ${JSON.stringify(options.caption)});
editor.dispatchEvent(new Event('input', { bubbles: true }));
return true;
}`));
if (!captionOk) {
throw new CommandExecutionError('填写抖音草稿表单失败: caption-editor-missing');
}
}
const visibilityOk = (await page.evaluate(`() => {
const visibility = Array.from(document.querySelectorAll('label')).find(
(el) => (el.textContent || '').includes(${JSON.stringify(options.visibilityLabel)})
);
if (!(visibility instanceof HTMLElement)) return false;
visibility.click();
return true;
}`));
if (!visibilityOk) {
throw new CommandExecutionError('填写抖音草稿表单失败: visibility-missing');
}
}
/**
* Switch the composer into custom-cover mode and expose the cover input with a
* stable selector for CDP file injection.
*/View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command — the editor may mount slightly later than the title fill
- Check the composer DOM for the caption editor's new selector and update '[contenteditable="true"]' in clis/douyin/draft.js:97
- Omit --caption temporarily if the caption is optional for your workflow, then add it manually in creator center
Example fix
// before
const editor = document.querySelector('[contenteditable="true"]');
// after: wait/poll for lazy-mounted editor
const editor = document.querySelector('[contenteditable="true"]')
|| document.querySelector('.editor-content[contenteditable]'); Defensive patterns
Strategy: try-catch
Try / catch
try {
await opencli.douyin.draft({ video, title, caption });
} catch (e) {
if (e.message.includes('caption-editor-missing')) {
// retry, or save draft without caption and add it manually
}
} Prevention
- Only pass --caption when needed; caption is optional
- Keep the caption selector broad (any contenteditable in the composer)
- Test against the live composer after known Douyin frontend releases
When it happens
Trigger: Passing a non-empty --caption while the composer page has no visible contenteditable editor — Douyin redesigned the caption box, the editor is inside an iframe, or the editor only mounts after the title is filled and a small delay passed.
Common situations: Douyin switched from contenteditable to a different editor component; caption field lazy-rendered; a modal overlay intercepting focus so the editor node is not present at query time.
Related errors
- 填写抖音草稿表单失败: title-input-missing
- 填写抖音草稿表单失败: visibility-missing
- 点击草稿按钮失败: ${result?.reason || 'unknown'}
- Waiting for 12306 tk auth cookie
- ChatGPT composer is not available on the current page.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/249565c38b3a0d70.
Report an issue: GitHub.