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

  1. Confirm the target video allows comments (check in a normal browser) — disabled comments make this failure permanent for that video.
  2. Retry with a longer wait/allow the page to fully load before running the comment script, or re-run the command.
  3. Verify the URL resolves directly to the video page (resolve short links like vm.tiktok.com first).
  4. Check the live DOM for the comment input selector; if TikTok renamed the attributes, update the library's selectors in buildCommentScript.
  5. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/eb2d163de94c71ca. Report an issue: GitHub.