jackwener/OpenCLI · error · CommandExecutionError

Browser session required for bilibili unfollow

Error message

Browser session required for bilibili unfollow

What it means

The bilibili unfollow command's func requires an authenticated browser page; if `page` is null/undefined it throws CommandExecutionError 'Browser session required for bilibili unfollow'. Following/unfollowing is a write action tied to a logged-in session, so running headless without a browser session is unsupported.

Source

Thrown at clis/bilibili/unfollow.js:53

cli({
    site: 'bilibili',
    name: 'unfollow',
    access: 'write',
    description: '取消关注 B站用户(官方 API,需登录)',
    domain: 'www.bilibili.com',
    strategy: Strategy.COOKIE,
    args: [
        {
            name: 'target',
            required: true,
            positional: true,
            help: '目标 UID / 用户名 / space.bilibili.com 链接',
        },
    ],
    columns: ['mid', 'name', 'status', 'url'],
    func: async (page, kwargs) => {
        if (!page) {
            throw new CommandExecutionError('Browser session required for bilibili unfollow');
        }
        const mid = await resolveTargetMid(page, kwargs.target);
        const self = await getSelfUid(page);
        if (mid === self) {
            throw new ArgumentError('Cannot unfollow yourself');
        }
        const attribute = await fetchRelationAttribute(page, mid);
        const url = `https://space.bilibili.com/${mid}`;
        // attribute 2=following, 6=mutual. Anything else means the viewer isn't
        // currently following — skip the POST and return idempotent status.
        if (attribute !== 2 && attribute !== 6) {
            return [{ mid, name: '', status: 'not-following', url }];
        }
        const payload = await apiPost(page, '/x/relation/modify', {
            params: { fid: mid, act: 2, re_src: 11 },
        });
        requireOkPayload(payload, 'relation modify');
        await waitForRelation(page, mid, (nextAttribute) => nextAttribute !== 2 && nextAttribute !== 6, 'not following');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Start/attach a browser session (log into bilibili) before running the unfollow command
  2. Re-open the session if it was closed; confirm `page` is being passed to the command func
  3. If scripting, use the session-aware runner rather than calling func(page=null) directly
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof page === 'undefined' || page === null) {
  throw new Error('Start a browser session (and log into bilibili) before running unfollow');
}

Type guard

function hasBrowserPage(ctx) {
  return ctx != null && typeof ctx === 'object' && typeof ctx.page === 'object' && ctx.page !== null;
}

Try / catch

try {
  await runCommand('bilibili unfollow', { target });
} catch (err) {
  if (err instanceof CommandExecutionError && /Browser session required/.test(err.message)) {
    await openBrowserSession();
    await runCommand('bilibili unfollow', { target }); // retry once
  } else throw err;
}

Prevention

When it happens

Trigger: Invoking the bilibili unfollow command (CLI or its func) without an active browser session — e.g. running the CLI outside the interactive browser-backed environment, the session was closed, or the command runner passed no page object.

Common situations: Running the command in CI or a script without the browser daemon; the browser session expired or was closed between commands; forgetting to start the interactive session before issuing browser-dependent commands.

Related errors


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