{"record":{"id":"da070872301df896","repo":"jackwener/OpenCLI","slug":"like-button-not-found-make-sure-you-are-logged-i-da0708","errorCode":null,"errorMessage":"Like button not found - make sure you are logged in","messagePattern":"Like button not found - make sure you are logged in","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/tiktok/unlike.js","lineNumber":17,"sourceCode":"import { cli } from '@jackwener/opencli/registry';\ncli({\n    site: 'tiktok',\n    name: 'unlike',\n    access: 'write',\n    description: 'Unlike a TikTok video',\n    domain: 'www.tiktok.com',\n    args: [\n        { name: 'url', required: true, positional: true, help: 'TikTok video URL' },\n    ],\n    columns: ['status', 'likes', 'url'],\n    pipeline: [\n        { navigate: { url: '${{ args.url }}', settleMs: 6000 } },\n        { evaluate: `(async () => {\n  const url = \\${{ args.url | json }};\n  const btn = document.querySelector('[data-e2e=\"like-icon\"]');\n  if (!btn) throw new Error('Like button not found - make sure you are logged in');\n  const container = btn.closest('button') || btn.closest('[role=\"button\"]') || btn;\n  const aria = (container.getAttribute('aria-label') || '').toLowerCase();\n  const color = window.getComputedStyle(btn).color;\n  const isLiked = aria.includes('unlike') || aria.includes('取消点赞') ||\n                  (color && (color.includes('255, 65') || color.includes('fe2c55')));\n  if (!isLiked) {\n    const count = document.querySelector('[data-e2e=\"like-count\"]');\n    return [{ status: 'Not liked', likes: count ? count.textContent.trim() : '-', url: url }];\n  }\n  container.click();\n  await new Promise(r => setTimeout(r, 2000));\n  const count = document.querySelector('[data-e2e=\"like-count\"]');\n  return [{ status: 'Unliked', likes: count ? count.textContent.trim() : '-', url: url }];\n})()\n` },\n    ],\n});\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/tiktok/unlike.js#L1-L35","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nawait run('tiktok unlike', { url: shortUrl });\n// after\nconst canonical = await resolveShortLink(shortUrl); // www.tiktok.com/@user/video/<id>\nawait run('tiktok unlike', { url: canonical });","handlingStrategy":"validation","validationCode":"await page.goto(url, { waitUntil: 'networkidle' });\nawait page.waitForSelector('[data-e2e=\"like-icon\"]', { timeout: 10000 })\n  .catch(() => { throw new Error('Like icon never rendered — check login session and video URL'); });","typeGuard":"function likeButtonExists(doc) {\n  return Boolean(doc.querySelector('[data-e2e=\"like-icon\"]'));\n}","tryCatchPattern":"try {\n  await run('tiktok unlike', { url });\n} catch (e) {\n  if (/Like button not found/.test(e.message)) {\n    console.error('Not logged in, video unavailable, or like selector changed');\n  } else {\n    throw e;\n  }\n}","preventionTips":["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"],"tags":["tiktok","scraping","selector-not-found","auth","dom"],"backgroundTag":"dom-element-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}