jackwener/OpenCLI · error · Error
Like button not found - make sure you are logged in
Error message
Like button not found - make sure you are logged in
What it means
The unlike script queries [data-e2e="like-icon"] on the video page and throws 'Like button not found - make sure you are logged in' if it is absent. Like controls only render for authenticated viewers on a fully loaded video page, so a missing element points to auth, rendering, or selector drift. The script otherwise relies on aria-label/color to detect the liked state.
Source
Thrown at clis/tiktok/unlike.js:17
import { cli } from '@jackwener/opencli/registry';
cli({
site: 'tiktok',
name: 'unlike',
access: 'write',
description: 'Unlike a TikTok video',
domain: 'www.tiktok.com',
args: [
{ name: 'url', required: true, positional: true, help: 'TikTok video URL' },
],
columns: ['status', 'likes', 'url'],
pipeline: [
{ navigate: { url: '${{ args.url }}', settleMs: 6000 } },
{ evaluate: `(async () => {
const url = \${{ args.url | json }};
const btn = document.querySelector('[data-e2e="like-icon"]');
if (!btn) throw new Error('Like button not found - make sure you are logged in');
const container = btn.closest('button') || btn.closest('[role="button"]') || btn;
const aria = (container.getAttribute('aria-label') || '').toLowerCase();
const color = window.getComputedStyle(btn).color;
const isLiked = aria.includes('unlike') || aria.includes('取消点赞') ||
(color && (color.includes('255, 65') || color.includes('fe2c55')));
if (!isLiked) {
const count = document.querySelector('[data-e2e="like-count"]');
return [{ status: 'Not liked', likes: count ? count.textContent.trim() : '-', url: url }];
}
container.click();
await new Promise(r => setTimeout(r, 2000));
const count = document.querySelector('[data-e2e="like-count"]');
return [{ status: 'Unliked', likes: count ? count.textContent.trim() : '-', url: url }];
})()
` },
],
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Log into TikTok in the automation browser (persist cookies) and retry
- Verify the URL opens a playable video page and the like icon exists in DevTools; update the selector if TikTok renamed it
- Increase the settle/wait time so the page fully renders before querying
- Use canonical www.tiktok.com/@user/video/<id> URLs instead of short links
Example fix
// before
await run('tiktok unlike', { url: shortUrl });
// after
const canonical = await resolveShortLink(shortUrl); // www.tiktok.com/@user/video/<id>
await run('tiktok unlike', { url: canonical }); Defensive patterns
Strategy: validation
Validate before calling
await page.goto(url, { waitUntil: 'networkidle' });
await page.waitForSelector('[data-e2e="like-icon"]', { timeout: 10000 })
.catch(() => { throw new Error('Like icon never rendered — check login session and video URL'); }); Type guard
function likeButtonExists(doc) {
return Boolean(doc.querySelector('[data-e2e="like-icon"]'));
} Try / catch
try {
await run('tiktok unlike', { url });
} catch (e) {
if (/Like button not found/.test(e.message)) {
console.error('Not logged in, video unavailable, or like selector changed');
} else {
throw e;
}
} Prevention
- Maintain a logged-in TikTok session for like/unlike operations
- Use canonical www.tiktok.com/@user/video/<id> URLs
- Wait on the selector rather than a fixed settle time
- Re-check [data-e2e="like-icon"] after TikTok UI updates
When it happens
Trigger: Calling the unlike command on a URL where no [data-e2e="like-icon"] element exists: unauthenticated session, video removed/private/region-blocked, page not rendered within the 6s settle, or TikTok changed the data-e2e attribute.
Common situations: Expired cookies; headless run without login state; short-share links landing on interstitials; TikTok A/B tests renaming data-e2e attributes; photo-post layouts that omit the video like icon.
Related errors
- Favorites button not found - make sure you are logged in
- BUTTON_NOT_FOUND: Follow button not on profile page (logged
- BUTTON_NOT_FOUND
- TikTok returned no notifications
- Search failed: HTTP ${res.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/da070872301df896.
Report an issue: GitHub.