jackwener/OpenCLI · error · Error
BUTTON_NOT_FOUND: Post button never became enabled (text not
Error message
BUTTON_NOT_FOUND: Post button never became enabled (text not registered or selectors changed)
What it means
After typing the comment text, `buildCommentScript` waits up to 4 seconds for the Post/发布/发送 button to become enabled. If it never enables (or is never found), the script calls `ensureNoRateLimitOrThrow()` and then throws `BUTTON_NOT_FOUND: Post button never became enabled ...`. Typically the typed text never registered in TikTok's React-controlled contenteditable, or a rate limit is suppressing the button state.
Source
Thrown at clis/tiktok/comment.js:79
}
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();
throw new Error('BUTTON_NOT_FOUND: Post button never became enabled (text not registered or selectors changed)');
}
const postBtn = findButtonByText(['Post', '发布', '发送']);
postBtn.click();
// State verification: a new comment-level-1 element should appear.
const flipped = await waitFor(
() => document.querySelectorAll('[data-e2e="comment-level-1"]').length > beforeCount,
{ timeoutMs: 8000 },
);
if (!flipped) {
ensureNoRateLimitOrThrow();
throw new Error('STATE_VERIFY_FAIL: comment count did not increase within 8s; comment may or may not have been recorded server-side');
}
ensureNoRateLimitOrThrow();
return [{View on GitHub (pinned to 49907e53dc)
Solutions
- Check for and respect a TikTok comment rate limit — wait (minutes to hours) before retrying; the script already routes rate-limit cases through ensureNoRateLimitOrThrow first.
- Re-run the command; a single failed injection is often transient.
- Simplify the comment text (plain ASCII, no leading/trailing whitespace) to rule out injection/encoding issues.
- Verify in a headed browser that typing manually enables the Post button; if manual typing also fails, the account/video is restricted.
- If buttons exist but never enable, TikTok changed the button markup/labels — update the selector/text list in buildCommentScript.
Defensive patterns
Strategy: try-catch
Validate before calling
// avoid predictable automation: non-empty plain text, sane pacing
const safeText = text.trim();
if (!safeText) throw new Error('comment text is empty');
await enforceMinInterval(accountId, 60 * 1000); // keep >1 min between comments per account Try / catch
try {
await tiktok.comment({ url: videoUrl, text });
} catch (e) {
if (String(e.message).startsWith('BUTTON_NOT_FOUND') && /Post button/.test(e.message)) {
if (await isRateLimited(accountId)) {
await sleep(minutes(30)); // cool-down then requeue
return queueComment(accountId, videoUrl, text);
}
return { skipped: true, reason: 'post-button-never-enabled' };
}
throw e;
} Prevention
- Rate-limit comments per account with generous cool-downs to avoid TikTok soft bans.
- Keep comment text simple (plain ASCII, trimmed) so React state updates reliably.
- Retry once before giving up; a single failed injection is often transient.
- Periodically confirm Post button labels/attributes ('Post', '发布', '发送') against the live TikTok UI.
When it happens
Trigger: Calling `tiktok comment` when execCommand text injection didn't trigger TikTok's React state so the Post button stays disabled; the comment text is empty or only whitespace after injection; TikTok is rate-limiting the account's commenting; the button's selector/label changed in a frontend update.
Common situations: Commenting repeatedly in a short window (account soft-limited by TikTok); special characters or emoji breaking the injection; headless browser where contenteditable focus/insert events don't propagate; TikTok redesign renaming button labels or aria-disabled semantics.
Related errors
- BUTTON_NOT_FOUND: comment input not found (page not rendered
- TikTok Studio item_list failed: ${statusMsg || statusCode}
- TikTok Studio item_list failed: ${detail}
- STATE_VERIFY_FAIL: follow button did not flip to Following w
- Search failed: HTTP ${res.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9c118f64a074806a.
Report an issue: GitHub.