jackwener/OpenCLI · error · Error
BUTTON_NOT_FOUND: comment input not found (page not rendered
Error message
BUTTON_NOT_FOUND: comment input not found (page not rendered, comments disabled, or selectors changed)
What it means
`buildCommentScript` runs in the page to post a TikTok comment: it locates the comment input via `[data-e2e="comment-input"] [contenteditable="true"]` (falling back to any contenteditable). If no input element exists it throws `BUTTON_NOT_FOUND: comment input not found ...`, an in-page Error surfaced by `postComment`. The library treats a missing input as 'cannot comment here' — the page never rendered a comment box.
Source
Thrown at clis/tiktok/comment.js:60
ensureLoggedInOrThrow();
ensureNoRateLimitOrThrow();
// Expand the comment panel if it is collapsed (vertical feed pages).
const commentIcon = document.querySelector('[data-e2e="comment-icon"]');
if (commentIcon) {
const cBtn = commentIcon.closest('button') || commentIcon.closest('[role="button"]') || commentIcon;
cBtn.click();
await waitFor(() => Boolean(
document.querySelector('[data-e2e="comment-input"] [contenteditable="true"]')
), { timeoutMs: 4000 });
}
const beforeCount = document.querySelectorAll('[data-e2e="comment-level-1"]').length;
const input = document.querySelector('[data-e2e="comment-input"] [contenteditable="true"]')
|| document.querySelector('[contenteditable="true"]');
if (!input) {
throw new Error('BUTTON_NOT_FOUND: comment input not found (page not rendered, comments disabled, or selectors changed)');
}
input.focus();
// execCommand is deprecated but still the only reliable way to inject
// text into TikTok's contenteditable so its React tree picks up the
// value; replicating with InputEvent fires but TikTok ignores it.
document.execCommand('insertText', false, commentText);
// Wait for the post button to become enabled — TikTok disables it
// until non-empty text is detected by their input handler.
const postReady = await waitFor(() => {
const candidate = findButtonByText(['Post', '发布', '发送']);
if (!candidate) return false;
const ariaDisabled = candidate.getAttribute && candidate.getAttribute('aria-disabled');
return !candidate.disabled && ariaDisabled !== 'true';
}, { timeoutMs: 4000 });
if (!postReady) {
ensureNoRateLimitOrThrow();View on GitHub (pinned to 49907e53dc)
Solutions
- Confirm the target video allows comments (check in a normal browser) — disabled comments make this failure permanent for that video.
- Retry with a longer wait/allow the page to fully load before running the comment script, or re-run the command.
- Verify the URL resolves directly to the video page (resolve short links like vm.tiktok.com first).
- Check the live DOM for the comment input selector; if TikTok renamed the attributes, update the library's selectors in buildCommentScript.
- Ensure you are logged in — logged-out views may not render the comment input at all.
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check: does the video allow comments?
const meta = await fetch(`https://www.tiktok.com/oembed?url=${encodeURIComponent(videoUrl)}`).then(r => r.json()).catch(() => null);
if (!meta) throw new Error('URL is not a resolvable TikTok video'); Try / catch
try {
await tiktok.comment({ url: videoUrl, text });
} catch (e) {
if (String(e.message).startsWith('BUTTON_NOT_FOUND') && /comment input/.test(e.message)) {
// comments disabled / not rendered / selectors changed
console.warn(`Cannot comment on ${videoUrl}: comments likely disabled or page not loaded.`);
return { skipped: true, reason: 'comment-input-missing' };
}
throw e;
} Prevention
- Filter target videos to those with comments enabled before batch commenting.
- Resolve short links (vm.tiktok.com) to full video URLs first.
- Wait for full page render before commenting; add a small settle delay.
- After TikTok redesigns, verify data-e2e="comment-input" still exists in the DOM.
When it happens
Trigger: Calling `tiktok comment --url <video>` (postComment -> script) when the video page has comments disabled by the creator, the page didn't finish rendering before the script ran, the URL points to a non-video page (profile/short link that didn't resolve), or TikTok changed the data-e2e attributes/selector structure.
Common situations: Commenting on videos with comments turned off; slow network/first render racing the script; headless rendering stuck on a consent or login wall; TikTok A/B redesign removing `data-e2e="comment-input"`; posting to a deleted/private video.
Related errors
- BUTTON_NOT_FOUND: Post button never became enabled (text not
- Could not find Antigravity input box
- Could not find input box
- Could not find antigravity.agentSidePanelInputBox
- Could not find Antigravity input box
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/eb2d163de94c71ca.
Report an issue: GitHub.