jackwener/OpenCLI · error · Error
STATE_VERIFY_FAIL: comment count did not increase within 8s;
Error message
STATE_VERIFY_FAIL: comment count did not increase within 8s; comment may or may not have been recorded server-side
What it means
buildCommentScript polls the DOM inside the TikTok page for 8 seconds waiting for the top-level comment count to increase after a comment is submitted. If the count never increases, the library throws STATE_VERIFY_FAIL to signal that it could not confirm the comment was posted. The message deliberately notes the comment may still have been recorded server-side, since TikTok's UI can lag or fail to re-render the comment list even when the API call succeeded.
Source
Thrown at clis/tiktok/comment.js:92
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 [{
url: location.href,
text: commentText,
result: 'posted',
}];
})()
`;
}
async function postComment(page, args) {
const { url } = parseTikTokVideoUrl(args.url);
const text = requireCommentText(args.text);
const throwFailure = (error) => throwButtonWalkerError(error, {
authMessage: 'TikTok requires login to post comments',View on GitHub (pinned to 49907e53dc)
Solutions
- Wait a few seconds and re-fetch the video's comments via the API to check whether the comment actually landed before retrying — do not blindly repost or you may double-comment.
- Retry the comment once after a short delay; if the text is identical, check for duplicates first.
- Slow down posting cadence and add jitter between comments to avoid soft rate limiting.
- If it reproduces across all videos, verify the page still contains '[data-e2e="comment-level-1"]' elements (TikTok may have changed the attribute) and update the selector.
Example fix
// before
const flipped = await waitFor(
() => document.querySelectorAll('[data-e2e="comment-level-1"]').length > beforeCount,
{ timeoutMs: 8000 },
);
// after
const flipped = await waitFor(
() => document.querySelectorAll('[data-e2e="comment-level-1"]').length > beforeCount,
{ timeoutMs: 20000 }, // allow slow renders / throttled comment lists
); Defensive patterns
Strategy: retry
Try / catch
// STATE_VERIFY_FAIL is ambiguous: verify before retrying to avoid duplicates
try {
await postComment(videoUrl, text);
} catch (e) {
if (String(e.message).startsWith('STATE_VERIFY_FAIL')) {
const existing = await listComments(videoUrl);
if (!existing.some(c => c.text === text)) {
await sleep(3000);
await postComment(videoUrl, text);
}
} else throw e;
} Prevention
- Keep a local record of posted comment texts and check before retrying.
- Space out comment submissions to avoid soft rate limiting.
- Run on a stable, non-proxied browser session with adequate resources.
- After a failure, verify server-side via the comments API rather than assuming failure.
When it happens
Trigger: Calling postComment (or the generated browser script) on a TikTok video where the '[data-e2e="comment-level-1"]' element count does not grow within 8s — e.g. comment submitted but rendered into a collapsed/filtered list, slow page, rate-limited silently, or the selector changed after a TikTok UI update.
Common situations: Posting many comments in quick succession so TikTok soft-throttles rendering; posting on videos with 'filtered comments' (only author-approved comments shown); running on a slow/proxied browser session where the 8s timeout is too short; TikTok shipping a DOM update that breaks the data-e2e selector.
Related errors
- Unexpected 12306 probe: ${JSON.stringify(probe)}
- ChatGPT did not create a conversation URL after sending the
- ChatWise response
- Could not switch to ${wantModel} model
- No Claude response appeared within ${timeoutSeconds}s. Re-ru
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/8f2bc6800600ce03.
Report an issue: GitHub.