jackwener/OpenCLI · error · CommandExecutionError

Browser session required

Error message

Browser session required

What it means

CommandExecutionError thrown when the reddit subscribed command runs without an active browser session. The command fetches /api/me.json and /subreddits/mine/subscriptions.json with cookie credentials inside the browser, so a page handle is mandatory; without one the command fails before any network call.

Source

Thrown at clis/reddit/subscribed.js:70

    };
}

cli({
    site: 'reddit',
    name: 'subscribed',
    description: 'List subreddits you are subscribed to',
    access: 'read',
    domain: 'reddit.com',
    strategy: Strategy.COOKIE,
    browser: true,
    args: [
        { name: 'limit', type: 'int', default: 100, help: `Max subreddits to return (1-${REDDIT_SUBSCRIBED_MAX_LIMIT}, auto-paginates)` },
    ],
    columns: ['id', 'subreddit', 'title', 'subscribers', 'description', 'url'],
    func: async (page, kwargs) => {
        const limit = parseRedditSubscribedLimit(kwargs.limit);
        if (!page)
            throw new CommandExecutionError('Browser session required');
        await page.goto('https://www.reddit.com');
        const result = unwrapEvaluateResult(await page.evaluate(`(async () => {
      ${BROWSER_JSON_SNIFF_FN}
      try {
        // fetchJsonOrLoginWall sniffs HTML responses (login wall / WAF / rate-limit
        // page) and returns a structured { __loginWall, status, url, ... } sentinel
        // instead of letting JSON.parse blow up with "Unexpected token '<'".
        const me = await fetchJsonOrLoginWall('/api/me.json?raw_json=1', { credentials: 'include' });
        if (me && me.__loginWall) {
          return { kind: 'login-wall', sentinel: me, where: '/api/me.json' };
        }
        if (me && me.error === 401 || me && me.error === 403) {
          return { kind: 'auth', detail: 'Reddit /api/me.json returned HTTP ' + me.error };
        }
        if (me && me.error) {
          return { kind: 'http', httpStatus: me.error, where: '/api/me.json' };
        }
        const username = me?.data?.name || me?.name;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the command in the library's browser mode so a page session is created before func executes
  2. Ensure a Chromium/Playwright-compatible browser is installed and launchable in your environment
  3. Log into reddit.com in that browser session — listing subscriptions requires authenticated cookies
  4. If embedding, pass a real page object (not null) when calling the command function

Example fix

// before
await redditSubscribed(null, { limit: 100 }) // throws
// after
const page = await browser.newPage();
await loginReddit(page);
await redditSubscribed(page, { limit: 100 });
Defensive patterns

Strategy: validation

Validate before calling

if (!page || typeof page.goto !== 'function') throw new Error('subscribed requires an active browser page');

Type guard

function hasBrowserPage(p){ return !!p && typeof p.goto === 'function' && typeof p.evaluate === 'function'; }

Try / catch

try { const rows = await cli.redditSubscribed({ limit }); }
catch (e) { if (e.message === 'Browser session required') { const page = await launchBrowserAndLogin(); return cli.redditSubscribed({ limit }, { page }); } throw e; }

Prevention

When it happens

Trigger: Invoking the subscribed command where the browser-backed `page` is null/undefined — no browser launched, headless environment without a browser, or calling the command function programmatically with page=null.

Common situations: Running the CLI in CI/containers without a browser; failing browser launch upstream; embedding the library and not supplying a page; forgetting to enable browser mode for this browser:true command.

Related errors


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