jackwener/OpenCLI · error · CommandExecutionError

Browser session required for linkedin-learning course

Error message

Browser session required for linkedin-learning course

What it means

The linkedin-learning course command is registered with browser: true and a COOKIE strategy: it requires an authenticated browser (Playwright) session to call LinkedIn's learning-api with the user's cookies. When the func is invoked with page === null — i.e. no browser session was created — this CommandExecutionError is thrown before any lookup happens.

Source

Thrown at clis/linkedin-learning/course.js:71

        released,
        url: `https://www.linkedin.com/learning/${slug}`,
    };
}

cli({
    site: 'linkedin-learning',
    name: 'course',
    access: 'read',
    description: 'Get LinkedIn Learning course detail by slug or course URL',
    domain: DOMAIN,
    strategy: Strategy.COOKIE,
    browser: true,
    args: [
        { name: 'slug', type: 'string', required: true, positional: true, help: 'Course slug (e.g. agentic-ai-build-your-first-agentic-ai-system) or full /learning/<slug> URL' },
    ],
    columns: ['title', 'slug', 'description', 'difficulty', 'duration_sec', 'videos_count', 'rating', 'rating_count', 'released', 'url'],
    func: async (page, args) => {
        if (!page) throw new CommandExecutionError('Browser session required for linkedin-learning course');
        const slug = parseSlug(args.slug);

        const url = `https://www.linkedin.com/learning-api/courses?q=slug&slug=${encodeURIComponent(slug)}`;
        const result = await fetchLinkedInLearningApi(page, url);
        if (!result?.json) {
            throw new CommandExecutionError(`LinkedIn Learning courses lookup failed: ${result?.error ?? 'no payload'}`);
        }
        const elements = result.json?.elements;
        if (!Array.isArray(elements)) {
            throw new CommandExecutionError('LinkedIn Learning courses lookup returned malformed payload: missing elements array');
        }
        const el = elements[0];
        if (!el) {
            throw new EmptyResultError(`No LinkedIn Learning course found for slug "${slug}"`);
        }
        const row = parseCourse(el, slug);
        if (!row) {
            throw new CommandExecutionError('LinkedIn Learning courses lookup returned malformed course detail: missing title');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the command with the browser session enabled (default path) so a logged-in Playwright page is provided.
  2. Ensure Playwright browsers are installed and launchable (e.g. npx playwright install) in the environment.
  3. Log in to linkedin.com in the session so the cookie-based authentication can be used.
Defensive patterns

Strategy: try-catch

Validate before calling

if (!browserPage) {
  throw new Error('linkedin-learning course requires a browser session; launch one first');
}

Type guard

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

Try / catch

try {
  await runCommand('linkedin-learning', 'course', [slug]);
} catch (e) {
  if (String(e.message).includes('Browser session required')) {
    await launchBrowserAndLogin(); // then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking the course command through a path that does not provision a browser page (headless harness, direct func call with null page, browser launch disabled/failed) so func receives page = null.

Common situations: Running the CLI in an environment where the embedded browser cannot launch (missing Playwright browsers, CI sandbox); calling the registered func programmatically without going through the browser bootstrap; disabling the --browser flag.

Related errors


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