jackwener/OpenCLI · error · CommandExecutionError

Browser session required for bilibili following

Error message

Browser session required for bilibili following

What it means

Like follow, the following command needs an authenticated browser page to call getSelfUid (or resolveUid) and read the Cookie-authenticated followings API. A falsy page aborts immediately with this CommandExecutionError.

Source

Thrown at clis/bilibili/following.js:19

import { cli, Strategy } from '@jackwener/opencli/registry';
import { CommandExecutionError } from '@jackwener/opencli/errors';
import { fetchJson, getSelfUid, resolveUid } from './utils.js';
cli({
    site: 'bilibili',
    name: 'following',
    access: 'read',
    description: '获取 Bilibili 用户的关注列表',
    domain: 'www.bilibili.com',
    strategy: Strategy.COOKIE,
    args: [
        { name: 'uid', positional: true, required: false, help: '目标用户 ID(默认为当前登录用户)' },
        { name: 'page', type: 'int', required: false, default: 1, help: '页码' },
        { name: 'limit', type: 'int', required: false, default: 50, help: '每页数量 (最大 50)' },
    ],
    columns: ['mid', 'name', 'sign', 'following', 'fans'],
    func: async (page, kwargs) => {
        if (!page)
            throw new CommandExecutionError('Browser session required for bilibili following');
        // 1. Resolve UID (default to self)
        const uid = kwargs.uid
            ? await resolveUid(page, kwargs.uid)
            : await getSelfUid(page);
        const pn = kwargs.page ?? 1;
        const ps = Math.min(kwargs.limit ?? 50, 50);
        // 2. Fetch following list (standard Cookie API, no Wbi signing needed)
        const payload = await fetchJson(page, `https://api.bilibili.com/x/relation/followings?vmid=${uid}&pn=${pn}&ps=${ps}&order=desc`);
        if (payload.code !== 0) {
            throw new CommandExecutionError(`获取关注列表失败: ${payload.message} (${payload.code})`);
        }
        const list = payload.data?.list || [];
        if (list.length === 0) {
            return [{ mid: '-', name: `共 ${payload.data?.total ?? 0} 人关注,当前页无数据`, sign: '', following: '', fans: '' }];
        }
        // 3. Map to output
        return list.map((u) => ({
            mid: u.mid,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Establish the browser session (login) before running the command.
  2. Pass a UID explicitly if supported, but the page requirement still stands — restart the session.
  3. Check that your automation keeps the page/browser alive between calls.

Example fix

// before
const rows = await cli.func(null, { uid: '9469745' });
// after
const page = await getSession().ensurePage();
const rows = await cli.func(page, { uid: '9469745' });
Defensive patterns

Strategy: validation

Validate before calling

if (!session?.page) throw new Error('establish a logged-in browser session before listing followings');

Type guard

function hasLivePage(ctx) {
  return ctx != null && ctx.page != null && !ctx.page.isClosed?.();
}

Try / catch

try {
  await followingCommand(page, kwargs);
} catch (e) {
  if (String(e.message).includes('Browser session required')) {
    const p = await ensureLoggedInPage();
    return followingCommand(p, kwargs);
  }
  throw e;
}

Prevention

When it happens

Trigger: Invoking bilibili following without an active/logged-in browser session, or when browser launch failed silently.

Common situations: CI pipelines without a browser profile, expired session where the page handle was discarded, calling the func programmatically with page=null.

Related errors


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