jackwener/OpenCLI · error · CommandExecutionError

Browser session required

Error message

Browser session required

What it means

clis/reddit/upvoted.js throws CommandExecutionError('Browser session required') when the `page` argument injected into its func is falsy. Listing upvoted posts requires executing fetches inside the logged-in Reddit page via page.evaluate, so a live browser session is a hard prerequisite. The check happens before any navigation, at upvoted.js:17.

Source

Thrown at clis/reddit/upvoted.js:17

import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
    site: 'reddit',
    name: 'upvoted',
    access: 'read',
    description: 'Browse your upvoted Reddit posts',
    domain: 'reddit.com',
    strategy: Strategy.COOKIE,
    browser: true,
    args: [
        { name: 'limit', type: 'int', default: 15 },
    ],
    columns: ['title', 'subreddit', 'score', 'comments', 'url'],
    func: async (page, kwargs) => {
        if (!page)
            throw new CommandExecutionError('Browser session required');
        await page.goto('https://www.reddit.com');
        const result = await page.evaluate(`(async () => {
      try {
        // Get current username
        const meRes = await fetch('/api/me.json?raw_json=1', { credentials: 'include' });
        const me = await meRes.json();
        const username = me?.name || me?.data?.name;
        if (!username) return { error: 'Not logged in — cannot determine username' };

        const limit = ${kwargs.limit};
        const res = await fetch('/user/' + username + '/upvoted.json?limit=' + limit + '&raw_json=1', {
          credentials: 'include'
        });
        const d = await res.json();
        return (d?.data?.children || []).map(c => ({
          title: c.data.title || '',
          subreddit: c.data.subreddit_name_prefixed || 'r/' + (c.data.subreddit || '?'),
          score: c.data.score || 0,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Launch the managed Chrome/daemon and reconnect the extension, then rerun.
  2. Check daemon/browser connect status before batch-running commands.
  3. When calling func programmatically, pass a valid page object (real session or mock).
  4. Wrap calls to catch this error and auto-start the session, then retry once.

Example fix

// before
const posts = await upvotedFunc(undefined, { limit: 15 }); // throws
// after
const page = await browser.getPage();
if (!page) throw new Error('start the browser daemon first');
const posts = await upvotedFunc(page, { limit: 15 });
Defensive patterns

Strategy: validation

Validate before calling

if (!(await browser.isConnected())) {
  await browser.start(); // ensure daemon + extension before listing upvoted posts
}

Type guard

function hasPage(x) { return x != null && typeof x.goto === 'function' && typeof x.evaluate === 'function'; }

Try / catch

try {
  const posts = await run(['reddit', 'upvoted']);
} catch (e) {
  if (e.message === 'Browser session required') {
    await browser.start();
    return await run(['reddit', 'upvoted']);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `reddit upvoted` with the browser daemon not running, the extension not connected, or the page handle missing (e.g. invoking the command func directly without a session).

Common situations: Daemon not started or crashed; running on a machine/container without Chrome; extension disconnected after browser restart; calling the internal func in tests without providing a page stub.

Related errors


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