jackwener/OpenCLI · error · Error

Favorites button not found - make sure you are logged in

Error message

Favorites button not found - make sure you are logged in

What it means

This browser-pipeline error is thrown by the TikTok unsave script when neither `[data-e2e="bookmark-icon"]` nor `[data-e2e="collect-icon"]` can be found in the rendered page. The selectors only exist for logged-in sessions viewing a video, so their absence almost always means the session is not authenticated (or the page layout changed). The script aborts rather than guessing which DOM node to click.

Source

Thrown at clis/tiktok/unsave.js:18

import { cli } from '@jackwener/opencli/registry';
cli({
    site: 'tiktok',
    name: 'unsave',
    access: 'write',
    description: 'Remove a TikTok video from Favorites',
    domain: 'www.tiktok.com',
    args: [
        { name: 'url', required: true, positional: true, help: 'TikTok video URL' },
    ],
    columns: ['status', 'url'],
    pipeline: [
        { navigate: { url: '${{ args.url }}', settleMs: 6000 } },
        { evaluate: `(async () => {
  const url = \${{ args.url | json }};
  const btn = document.querySelector('[data-e2e="bookmark-icon"]') ||
              document.querySelector('[data-e2e="collect-icon"]');
  if (!btn) throw new Error('Favorites 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();
  if (aria.includes('add to favorites') || aria.includes('收藏')) {
    if (!aria.includes('remove') && !aria.includes('取消')) {
      return [{ status: 'Not in Favorites', url: url }];
    }
  }
  container.click();
  await new Promise(r => setTimeout(r, 2000));
  return [{ status: 'Removed from Favorites', url: url }];
})()
` },
    ],
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log into TikTok in the browser profile/session used by the CLI, then retry.
  2. Open the video URL manually and confirm the favorites (bookmark) button is visible; if the page redirects to login, fix the session first.
  3. Increase the settle time after navigate if the page loads slowly.
  4. If TikTok changed its markup, inspect the button's data-e2e attribute and update the querySelector fallbacks in clis/tiktok/unsave.js.

Example fix

// before: selectors miss because page not logged in / attributes renamed
const btn = document.querySelector('[data-e2e="bookmark-icon"]') ||
            document.querySelector('[data-e2e="collect-icon"]');
if (!btn) throw new Error('Favorites button not found - make sure you are logged in');
// after: detect login wall explicitly and give a precise message
if (document.querySelector('[data-e2e="login-icon"], [href*="login"]')) {
  throw new Error('Not logged in: TikTok redirected to login page');
}
const btn = document.querySelector('[data-e2e="bookmark-icon"], [data-e2e="collect-icon"], [data-e2e="favorite-icon"]');
Defensive patterns

Strategy: try-catch

Validate before calling

// before running the pipeline, confirm the session can view the page
const res = await fetch(url, { headers: { cookie: sessionCookie } });
if (!res.ok || /login|signup/.test(await res.text().then(t => t.slice(0, 2000)))) {
  throw new Error('TikTok session is not logged in; refresh cookies before unsave');
}

Try / catch

try {
  await cli.tiktok.unsave(url);
} catch (e) {
  if (/Favorites button not found/.test(e.message)) {
    console.error('Session likely logged out or DOM changed; re-login and retry');
  } else throw e;
}

Prevention

When it happens

Trigger: Running the unsave pipeline against a video URL while the browser session has no valid TikTok login cookie; TikTok redirecting to a login/signup wall or an 'expired session' interstitial instead of the video page; a TikTok DOM update that renames the data-e2e attributes; the 6000ms settle time elapsing before the icon is rendered (slow page load).

Common situations: Expired or never-provided session cookies; running the CLI in a fresh browser profile without logging in; scraping from a region/IP that triggers TikTok's login wall; TikTok A/B testing new DOM attributes so the hardcoded selectors no longer match.

Related errors


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